From lstewart at netflix.com Mon Oct 3 04:37:38 2016 From: lstewart at netflix.com (Lawrence Stewart) Date: Mon, 3 Oct 2016 15:37:38 +1100 Subject: Inconsistent order for ngx_destroy_pool() and ngx_close_connection() Message-ID: Hi all, I need to pull kernel data using getsockopt() for a connection prior to the socket being closed. A pool cleanup handler registered with the ngx_connection_t's pool would seem to be the right way to do this, but ngx_http_close_connection() calls ngx_close_connection() prior to ngx_destroy_pool(), which means my cleanup handler sees a closed socket. A look through ngx_close_connection() and the functions it calls would lead me to believe it should be safe (and possible even desirable in an ordering sense) to destroy the connection's pool prior to calling ngx_close_connection(). There is an existence proof in the nginx tree that this is reasonable to do (see [1]) and there is also a comment in ngx_close_connection() that implies it expects that the connection's pool has already been destroyed i.e. /* we use ngx_cycle->log because c->log was in c->pool */ Are there some subtleties I'm missing, or is it correct and reasonable to always call ngx_destroy_pool() on a connection's pool prior to calling ngx_close_connection()? Cheers, Lawrence [1] http://lxr.nginx.org/source/src/http/modules/ngx_http_upstream_keepalive_module.c?v=nginx-1.10.1#0441 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Mon Oct 3 07:45:53 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 3 Oct 2016 10:45:53 +0300 Subject: Inconsistent order for ngx_destroy_pool() and ngx_close_connection() In-Reply-To: References: Message-ID: <20161003074553.GI8172@lo0.su> On Mon, Oct 03, 2016 at 03:37:38PM +1100, Lawrence Stewart wrote: > Hi all, > > I need to pull kernel data using getsockopt() for a connection prior to the > socket being closed. A pool cleanup handler registered with the > ngx_connection_t's pool would seem to be the right way to do this, but > ngx_http_close_connection() calls ngx_close_connection() prior to > ngx_destroy_pool(), which means my cleanup handler sees a closed socket. > > A look through ngx_close_connection() and the functions it calls would lead > me to believe it should be safe (and possible even desirable in an ordering > sense) to destroy the connection's pool prior to calling > ngx_close_connection(). If we talk about client connections, then c->log is allocated from c->pool, and c->read->log and c->write->log also use this log object, see ngx_event_accept(). A look through ngx_close_connection() shows that nearly every call it makes: ngx_log_error, ngx_del_timer, ngx_del_conn, ngx_del_event, ngx_delete_posted_event, and ngx_reusable_connection need c->log which would be destroyed if c->pool was destroyed. > There is an existence proof in the nginx tree that > this is reasonable to do (see [1]) and there is also a comment in > ngx_close_connection() that implies it expects that the connection's pool > has already been destroyed i.e. > > /* we use ngx_cycle->log because c->log was in c->pool */ This comment seems outdated since rev. c52408583801 which removed the ngx_destroy_pool(c->pool) call from ngx_close_connection(): : @@ -388,8 +387,6 @@ void ngx_close_connection(ngx_connection : c->fd = (ngx_socket_t) -1; : c->data = NULL; : : - ngx_destroy_pool(c->pool); : - : if (ngx_close_socket(fd) == -1) { : : /* we use ngx_cycle->log because c->log was in c->pool */ > Are there some subtleties I'm missing, or is it correct and reasonable to > always call ngx_destroy_pool() on a connection's pool prior to calling > ngx_close_connection()? On the contrary, the upstream connection's pool is destroyed before calling ngx_close_connection(), see ngx_http_upstream_next() and ngx_http_upstream_finalize_request(). This is safe because the upstream connection reuses the client connection's log, see ngx_http_upstream_connect(). From igor at sysoev.ru Mon Oct 3 10:33:34 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 03 Oct 2016 10:33:34 +0000 Subject: [njs] A "var" statement termination has been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/b3e83fa52345 branches: changeset: 186:b3e83fa52345 user: Igor Sysoev date: Fri Sep 30 14:11:27 2016 +0300 description: A "var" statement termination has been fixed. diffstat: njs/njs_parser.c | 19 +++- njs/njs_parser_expression.c | 1 - njs/test/njs_unit_test.c | 251 ++++++++++++++++++++++--------------------- 3 files changed, 146 insertions(+), 125 deletions(-) diffs (642 lines): diff -r 322359ec0913 -r b3e83fa52345 njs/njs_parser.c --- a/njs/njs_parser.c Wed Sep 28 19:52:05 2016 +0300 +++ b/njs/njs_parser.c Fri Sep 30 14:11:27 2016 +0300 @@ -717,7 +717,24 @@ njs_parser_var_statement(njs_vm_t *vm, n } while (token == NJS_TOKEN_COMMA); - return token; + /* + * A var statement must be terminated by semicolon, + * or by a close curly brace or by the end of line. + */ + switch (token) { + + case NJS_TOKEN_SEMICOLON: + case NJS_TOKEN_CLOSE_BRACE: + case NJS_TOKEN_END: + return token; + + default: + if (parser->lexer->prev_token == NJS_TOKEN_LINE_END) { + return token; + } + + return NJS_TOKEN_ILLEGAL; + } } diff -r 322359ec0913 -r b3e83fa52345 njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Wed Sep 28 19:52:05 2016 +0300 +++ b/njs/njs_parser_expression.c Fri Sep 30 14:11:27 2016 +0300 @@ -474,7 +474,6 @@ njs_parser_assignment_expression(njs_vm_ } token = njs_parser_assignment_expression(vm, parser, NULL, token); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } diff -r 322359ec0913 -r b3e83fa52345 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Sep 28 19:52:05 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Sep 30 14:11:27 2016 +0300 @@ -837,13 +837,13 @@ static njs_unit_test_t njs_test[] = { nxt_string("null < ({})"), nxt_string("false") }, - { nxt_string("var a = { valueOf: function() { return 1 } } null < a"), - nxt_string("true") }, - - { nxt_string("var a = { valueOf: function() { return 'null' } } null < a"), + { nxt_string("var a = { valueOf: function() { return 1 } }; null < a"), + nxt_string("true") }, + + { nxt_string("var a = { valueOf: function() { return 'null' } };null < a"), nxt_string("false") }, - { nxt_string("var a = { valueOf: function() { return '1' } } null < a"), + { nxt_string("var a = { valueOf: function() { return '1' } }; null < a"), nxt_string("true") }, /**/ @@ -887,14 +887,14 @@ static njs_unit_test_t njs_test[] = { nxt_string("undefined < ({})"), nxt_string("false") }, - { nxt_string("var a = { valueOf: function() { return 1 } } undefined < a"), + { nxt_string("var a = { valueOf: function() { return 1 } }; undefined < a"), nxt_string("false") }, - { nxt_string("var a = { valueOf: function() { return 'undefined' } }" + { nxt_string("var a = { valueOf: function() { return 'undefined' } };" "undefined < a"), nxt_string("false") }, - { nxt_string("var a = { valueOf: function() { return '1' } }" + { nxt_string("var a = { valueOf: function() { return '1' } };" "undefined < a"), nxt_string("false") }, @@ -1083,16 +1083,16 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; a = ++a"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } } a = ++a"), - nxt_string("2") }, - - { nxt_string("var a = { valueOf: function() { return '1' } } a = ++a"), + { nxt_string("var a = { valueOf: function() { return 1 } }; a = ++a"), nxt_string("2") }, - { nxt_string("var a = { valueOf: function() { return [1] } } a = ++a"), + { nxt_string("var a = { valueOf: function() { return '1' } }; a = ++a"), + nxt_string("2") }, + + { nxt_string("var a = { valueOf: function() { return [1] } }; a = ++a"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } } a = ++a"), + { nxt_string("var a = { valueOf: function() { return {} } }; a = ++a"), nxt_string("NaN") }, /**/ @@ -1109,19 +1109,19 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; var b = ++a; a +' '+ b"), nxt_string("NaN NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } }" + { nxt_string("var a = { valueOf: function() { return 1 } };" "var b = ++a; a +' '+ b"), nxt_string("2 2") }, - { nxt_string("var a = { valueOf: function() { return '1' } }" + { nxt_string("var a = { valueOf: function() { return '1' } };" "var b = ++a; a +' '+ b"), nxt_string("2 2") }, - { nxt_string("var a = { valueOf: function() { return [1] } }" + { nxt_string("var a = { valueOf: function() { return [1] } };" "var b = ++a; a +' '+ b"), nxt_string("NaN NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } }" + { nxt_string("var a = { valueOf: function() { return {} } };" "var b = ++a; a +' '+ b"), nxt_string("NaN NaN") }, @@ -1139,16 +1139,16 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; a++"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } } a++"), - nxt_string("1") }, - - { nxt_string("var a = { valueOf: function() { return '1' } } a++"), + { nxt_string("var a = { valueOf: function() { return 1 } }; a++"), nxt_string("1") }, - { nxt_string("var a = { valueOf: function() { return [1] } } a++"), + { nxt_string("var a = { valueOf: function() { return '1' } }; a++"), + nxt_string("1") }, + + { nxt_string("var a = { valueOf: function() { return [1] } }; a++"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } } a++"), + { nxt_string("var a = { valueOf: function() { return {} } }; a++"), nxt_string("NaN") }, /**/ @@ -1165,16 +1165,16 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; a = a++"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } } a = a++"), - nxt_string("1") }, - - { nxt_string("var a = { valueOf: function() { return '1' } } a = a++"), + { nxt_string("var a = { valueOf: function() { return 1 } }; a = a++"), nxt_string("1") }, - { nxt_string("var a = { valueOf: function() { return [1] } } a = a++"), + { nxt_string("var a = { valueOf: function() { return '1' } }; a = a++"), + nxt_string("1") }, + + { nxt_string("var a = { valueOf: function() { return [1] } }; a = a++"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } } a = a++"), + { nxt_string("var a = { valueOf: function() { return {} } }; a = a++"), nxt_string("NaN") }, /**/ @@ -1191,19 +1191,19 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; var b = a++; a +' '+ b"), nxt_string("NaN NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } }" + { nxt_string("var a = { valueOf: function() { return 1 } };" "var b = a++; a +' '+ b"), nxt_string("2 1") }, - { nxt_string("var a = { valueOf: function() { return '1' } }" + { nxt_string("var a = { valueOf: function() { return '1' } };" "var b = a++; a +' '+ b"), nxt_string("2 1") }, - { nxt_string("var a = { valueOf: function() { return [1] } }" + { nxt_string("var a = { valueOf: function() { return [1] } };" "var b = a++; a +' '+ b"), nxt_string("NaN NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } }" + { nxt_string("var a = { valueOf: function() { return {} } };" "var b = a++; a +' '+ b"), nxt_string("NaN NaN") }, @@ -1247,16 +1247,16 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; a = --a"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return 1} } a = --a"), - nxt_string("0") }, - - { nxt_string("var a = { valueOf: function() { return '1'} } a = --a"), + { nxt_string("var a = { valueOf: function() { return 1} }; a = --a"), nxt_string("0") }, - { nxt_string("var a = { valueOf: function() { return [1]} } a = --a"), + { nxt_string("var a = { valueOf: function() { return '1'} }; a = --a"), + nxt_string("0") }, + + { nxt_string("var a = { valueOf: function() { return [1]} }; a = --a"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } } a = --a"), + { nxt_string("var a = { valueOf: function() { return {} } }; a = --a"), nxt_string("NaN") }, /**/ @@ -1273,19 +1273,19 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; var b = --a; a +' '+ b"), nxt_string("NaN NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } }" + { nxt_string("var a = { valueOf: function() { return 1 } };" "var b = --a; a +' '+ b"), nxt_string("0 0") }, - { nxt_string("var a = { valueOf: function() { return '1' } }" + { nxt_string("var a = { valueOf: function() { return '1' } };" "var b = --a; a +' '+ b"), nxt_string("0 0") }, - { nxt_string("var a = { valueOf: function() { return [1] } }" + { nxt_string("var a = { valueOf: function() { return [1] } };" "var b = --a; a +' '+ b"), nxt_string("NaN NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } }" + { nxt_string("var a = { valueOf: function() { return {} } };" "var b = --a; a +' '+ b"), nxt_string("NaN NaN") }, @@ -1303,16 +1303,16 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; a--"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } } a--"), - nxt_string("1") }, - - { nxt_string("var a = { valueOf: function() { return '1' } } a--"), + { nxt_string("var a = { valueOf: function() { return 1 } }; a--"), nxt_string("1") }, - { nxt_string("var a = { valueOf: function() { return [1] } } a--"), + { nxt_string("var a = { valueOf: function() { return '1' } }; a--"), + nxt_string("1") }, + + { nxt_string("var a = { valueOf: function() { return [1] } }; a--"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } } a--"), + { nxt_string("var a = { valueOf: function() { return {} } }; a--"), nxt_string("NaN") }, /**/ @@ -1329,16 +1329,16 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; a = a--"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } } a = a--"), - nxt_string("1") }, - - { nxt_string("var a = { valueOf: function() { return '1' } } a = a--"), + { nxt_string("var a = { valueOf: function() { return 1 } }; a = a--"), nxt_string("1") }, - { nxt_string("var a = { valueOf: function() { return [1] } } a = a--"), + { nxt_string("var a = { valueOf: function() { return '1' } }; a = a--"), + nxt_string("1") }, + + { nxt_string("var a = { valueOf: function() { return [1] } }; a = a--"), nxt_string("NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } } a = a--"), + { nxt_string("var a = { valueOf: function() { return {} } }; a = a--"), nxt_string("NaN") }, /**/ @@ -1355,19 +1355,19 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = {}; var b = a--; a +' '+ b"), nxt_string("NaN NaN") }, - { nxt_string("var a = { valueOf: function() { return 1 } }" + { nxt_string("var a = { valueOf: function() { return 1 } };" "var b = a--; a +' '+ b"), nxt_string("0 1") }, - { nxt_string("var a = { valueOf: function() { return '1' } }" + { nxt_string("var a = { valueOf: function() { return '1' } };" "var b = a--; a +' '+ b"), nxt_string("0 1") }, - { nxt_string("var a = { valueOf: function() { return [1] } }" + { nxt_string("var a = { valueOf: function() { return [1] } };" "var b = a--; a +' '+ b"), nxt_string("NaN NaN") }, - { nxt_string("var a = { valueOf: function() { return {} } }" + { nxt_string("var a = { valueOf: function() { return {} } };" "var b = a--; a +' '+ b"), nxt_string("NaN NaN") }, @@ -1934,7 +1934,7 @@ static njs_unit_test_t njs_test[] = "x.a +' '+ x.b +' '+ y.a"), nxt_string("1 2 3") }, - { nxt_string("var a=''; var o = {a:1, b:2}" + { nxt_string("var a=''; var o = {a:1, b:2};" "for (p in o) { a += p +':'+ o[p] +',' } a"), nxt_string("a:1,b:2,") }, @@ -2144,14 +2144,14 @@ static njs_unit_test_t njs_test[] = { nxt_string("a = []; a.concat([])"), nxt_string("") }, - { nxt_string("var s = { toString: function() { return 'S' } }" - "var v = { toString: 8, valueOf: function() { return 'V' } }" + { nxt_string("var s = { toString: function() { return 'S' } };" + "var v = { toString: 8, valueOf: function() { return 'V' } };" "var o = [9]; o.join = function() { return 'O' };" "var a = [1,2,3,[4,5,6],s,v,o]; a.join('')"), nxt_string("1234,5,6SVO") }, - { nxt_string("var s = { toString: function() { return 'S' } }" - "var v = { toString: 8, valueOf: function() { return 'V' } }" + { nxt_string("var s = { toString: function() { return 'S' } };" + "var v = { toString: 8, valueOf: function() { return 'V' } };" "var o = [9]; o.join = function() { return 'O' };" "var a = [1,2,3,[4,5,6],s,v,o]; a"), nxt_string("1,2,3,4,5,6,S,V,O") }, @@ -2534,7 +2534,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = ['1','2','3','4','5','6']; a.sort()"), nxt_string("1,2,3,4,5,6") }, - { nxt_string("var o = { toString: function() { return 5 } }" + { nxt_string("var o = { toString: function() { return 5 } };" "var a = [6,o,4,3,2,1]; a.sort()"), nxt_string("1,2,3,4,5,6") }, @@ -2564,8 +2564,8 @@ static njs_unit_test_t njs_test[] = /* Strings. */ - { nxt_string("var a = '0123456789' + '012345'" - "var b = 'abcdefghij' + 'klmnop'" + { nxt_string("var a = '0123456789' + '012345';" + "var b = 'abcdefghij' + 'klmnop';" " a = b"), nxt_string("abcdefghijklmnop") }, @@ -2852,11 +2852,11 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abc'.charAt(-Infinity)"), nxt_string("") }, - { nxt_string("var o = { valueOf: function() {return 2} }" + { nxt_string("var o = { valueOf: function() {return 2} };" "'abc'.charAt(o)"), nxt_string("c") }, - { nxt_string("var o = { toString: function() {return '2'} }" + { nxt_string("var o = { toString: function() {return '2'} };" "'abc'.charAt(o)"), nxt_string("c") }, @@ -3162,20 +3162,20 @@ static njs_unit_test_t njs_test[] = { nxt_string("'123456'.search(Number('45'))"), nxt_string("3") }, - { nxt_string("var r = { toString: function() { return '45' } }" - "'123456'.search(r)"), - nxt_string("3") }, - - { nxt_string("var r = { toString: function() { return 45 } }" + { nxt_string("var r = { toString: function() { return '45' } };" "'123456'.search(r)"), nxt_string("3") }, - { nxt_string("var r = { toString: function() { return /45/ } }" + { nxt_string("var r = { toString: function() { return 45 } };" + "'123456'.search(r)"), + nxt_string("3") }, + + { nxt_string("var r = { toString: function() { return /45/ } };" "'123456'.search(r)"), nxt_string("TypeError") }, { nxt_string("var r = { toString: function() { return /34/ }," - " valueOf: function() { return 45 } }" + " valueOf: function() { return 45 } };" "'123456'.search(r)"), nxt_string("3") }, @@ -3296,20 +3296,20 @@ static njs_unit_test_t njs_test[] = { nxt_string("'123456'.match(Number('45'))"), nxt_string("45") }, - { nxt_string("var r = { toString: function() { return '45' } }" - "'123456'.match(r)"), - nxt_string("45") }, - - { nxt_string("var r = { toString: function() { return 45 } }" + { nxt_string("var r = { toString: function() { return '45' } };" "'123456'.match(r)"), nxt_string("45") }, - { nxt_string("var r = { toString: function() { return /45/ } }" + { nxt_string("var r = { toString: function() { return 45 } };" + "'123456'.match(r)"), + nxt_string("45") }, + + { nxt_string("var r = { toString: function() { return /45/ } };" "'123456'.match(r)"), nxt_string("TypeError") }, { nxt_string("var r = { toString: function() { return /34/ }," - " valueOf: function() { return 45 } }" + " valueOf: function() { return 45 } };" "'123456'.match(r)"), nxt_string("45") }, @@ -3670,7 +3670,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = (0, function(a) { return a + 1 }(2)); a"), nxt_string("3") }, - { nxt_string("var a = +function f(a) { return a + 1 }(2)" + { nxt_string("var a = +function f(a) { return a + 1 }(2);" "var b = f(5); a"), nxt_string("ReferenceError") }, @@ -3680,40 +3680,40 @@ static njs_unit_test_t njs_test[] = { nxt_string("var o = {}; o.f = function(a) { return a * 2 }; o.f(5)"), nxt_string("10") }, - { nxt_string("var o = { x: 1, f: function() { return this.x } } o.f()"), + { nxt_string("var o = { x: 1, f: function() { return this.x } }; o.f()"), nxt_string("1") }, - { nxt_string("var o = { x: 1, f: function(a) { return this.x += a } }" + { nxt_string("var o = { x: 1, f: function(a) { return this.x += a } };" "o.f(5) +' '+ o.x"), nxt_string("6 6") }, - { nxt_string("var f = function(a) { return 3 } f.call()"), + { nxt_string("var f = function(a) { return 3 }; f.call()"), nxt_string("3") }, - { nxt_string("var f = function(a) { return this } f.call(5)"), + { nxt_string("var f = function(a) { return this }; f.call(5)"), nxt_string("5") }, - { nxt_string("var f = function(a, b) { return this + a } f.call(5, 1)"), + { nxt_string("var f = function(a, b) { return this + a }; f.call(5, 1)"), nxt_string("6") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "f.call(5, 1, 2)"), nxt_string("8") }, - { nxt_string("var f = function(a) { return 3 } f.apply()"), + { nxt_string("var f = function(a) { return 3 }; f.apply()"), nxt_string("3") }, - { nxt_string("var f = function(a) { return this } f.apply(5)"), + { nxt_string("var f = function(a) { return this }; f.apply(5)"), nxt_string("5") }, - { nxt_string("var f = function(a) { return this + a } f.apply(5, 1)"), + { nxt_string("var f = function(a) { return this + a }; f.apply(5, 1)"), nxt_string("TypeError") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "f.apply(5, [1, 2])"), nxt_string("8") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "f.apply(5, [1, 2], 3)"), nxt_string("8") }, @@ -3812,57 +3812,61 @@ static njs_unit_test_t njs_test[] = "concat.call(1,2,3, concat.yes)"), nxt_string("123OK") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1'); b('2', '3')"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1', '2'); b('3')"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1', 2, '3'); b()"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1'); b.call('0', '2', '3')"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1', '2'); b.call('0', '3')"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1', '2', '3'); b.call('0')"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1', '2', '3'); b.call()"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1'); b.apply('0', ['2', '3'])"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1', '2'); b.apply('0', ['3'])"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1', '2', '3'); b.apply('0')"), nxt_string("123") }, - { nxt_string("var f = function(a, b) { return this + a + b }" + { nxt_string("var f = function(a, b) { return this + a + b };" "var b = f.bind('1', '2', '3'); b.apply()"), nxt_string("123") }, + { nxt_string("function f(a, b) { return this + a + b }" + "var b = f.bind('1', '2', '3'); b.apply()"), + nxt_string("123") }, + { nxt_string("function F(a, b) { this.a = a + b }" - "var o = new F(1, 2)" + "var o = new F(1, 2);" "o.a"), nxt_string("3") }, { nxt_string("function F(a, b) { this.a = a + b; return { a: 7 } }" - "var o = new F(1, 2)" + "var o = new F(1, 2);" "o.a"), nxt_string("7") }, @@ -3978,9 +3982,9 @@ static njs_unit_test_t njs_test[] = nxt_string("35 ???? ???? /????/gi") }, { nxt_string("var r = /quick\\s(brown).+?(jumps)/ig;" - "var a = r.exec('The Quick Brown Fox Jumps Over The Lazy Dog')" - "a[0] +' '+ a[1] +' '+ a[2] +' '+ a[3] +' '+ " - "a.index +' '+ r.lastIndex +' '+ a.input"), + "var a = r.exec('The Quick Brown Fox Jumps Over The Lazy Dog');" + "a[0] +' '+ a[1] +' '+ a[2] +' '+ a[3] +' '+ " + "a.index +' '+ r.lastIndex +' '+ a.input"), nxt_string("Quick Brown Fox Jumps Brown Jumps undefined " "4 25 The Quick Brown Fox Jumps Over The Lazy Dog") }, @@ -4085,28 +4089,29 @@ static njs_unit_test_t njs_test[] = { nxt_string("var o = { valueOf: function() { return [3] } }; --o"), nxt_string("NaN") }, - { nxt_string("var o = { valueOf: function() { return '3' } } 10 - o"), + { nxt_string("var o = { valueOf: function() { return '3' } }; 10 - o"), nxt_string("7") }, - { nxt_string("var o = { valueOf: function() { return [3] } } 10 - o"), + { nxt_string("var o = { valueOf: function() { return [3] } }; 10 - o"), nxt_string("NaN") }, - { nxt_string("var o = { toString: function() { return 'OK' } } 'o:' + o"), + { nxt_string("var o = { toString: function() { return 'OK' } }; 'o:' + o"), nxt_string("o:OK") }, - { nxt_string("var o = { toString: function() { return [1] } } 'o:' + o"), + { nxt_string("var o = { toString: function() { return [1] } }; 'o:' + o"), nxt_string("TypeError") }, - { nxt_string("var a = { valueOf: function() { return '3' } }" - "var b = { toString: function() { return 10 - a + 'OK' } }" - "var c = { toString: function() { return b + 'YES' } }" + { nxt_string("var a = { valueOf: function() { return '3' } };" + "var b = { toString: function() { return 10 - a + 'OK' } };" + "var c = { toString: function() { return b + 'YES' } };" "'c:' + c"), nxt_string("c:7OKYES") }, { nxt_string("[1,2,3].valueOf()"), nxt_string("1,2,3") }, - { nxt_string("var o = { valueOf: function() { return 'OK' } } o.valueOf()"), + { nxt_string("var o = { valueOf: function() { return 'OK' } };" + "o.valueOf()"), nxt_string("OK") }, { nxt_string("false.__proto__ === true.__proto__"), @@ -4408,11 +4413,11 @@ static njs_unit_test_t njs_test[] = { nxt_string("new String([1,2,3])"), nxt_string("1,2,3") }, - { nxt_string("var o = { toString: function() { return 'OK' } }" + { nxt_string("var o = { toString: function() { return 'OK' } };" "String(o)"), nxt_string("OK") }, - { nxt_string("var o = { toString: function() { return 'OK' } }" + { nxt_string("var o = { toString: function() { return 'OK' } };" "new String(o)"), nxt_string("OK") }, @@ -4917,7 +4922,7 @@ static njs_unit_test_t njs_test[] = "d.toJSON(1)"), nxt_string("2011-06-24T06:00:12.625Z") }, - { nxt_string("var o = { toISOString: function() { return 'OK' } }" + { nxt_string("var o = { toISOString: function() { return 'OK' } };" "Date.prototype.toJSON.call(o, 1)"), nxt_string("OK") }, From igor at sysoev.ru Mon Oct 3 10:33:37 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 03 Oct 2016 10:33:37 +0000 Subject: [njs] Inclusive "new" operators and "new" operator calls without Message-ID: details: http://hg.nginx.org/njs/rev/8c2cea409034 branches: changeset: 187:8c2cea409034 user: Igor Sysoev date: Fri Sep 30 22:07:07 2016 +0300 description: Inclusive "new" operators and "new" operator calls without parenthesis are supported. diffstat: njs/njs_parser_expression.c | 135 +++++++++++++++++++++++++++++++++++-------- njs/test/njs_unit_test.c | 101 ++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 25 deletions(-) diffs (378 lines): diff -r b3e83fa52345 -r 8c2cea409034 njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Fri Sep 30 14:11:27 2016 +0300 +++ b/njs/njs_parser_expression.c Fri Sep 30 22:07:07 2016 +0300 @@ -70,6 +70,8 @@ static njs_token_t njs_parser_post_inc_d njs_parser_t *parser, njs_token_t token); static njs_token_t njs_parser_call_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); +static njs_token_t njs_parser_new_expression(njs_vm_t *vm, + njs_parser_t *parser, njs_token_t token); static njs_token_t njs_parser_property_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); static njs_token_t njs_parser_property_brackets(njs_vm_t *vm, @@ -894,27 +896,20 @@ static njs_token_t njs_parser_call_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) { - nxt_bool_t ctor; njs_parser_node_t *func, *node; - ctor = 0; - if (token == NJS_TOKEN_NEW) { - token = njs_parser_token(parser); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - return token; - } + token = njs_parser_new_expression(vm, parser, token); - ctor = 1; + } else { + token = njs_parser_terminal(vm, parser, token); } - token = njs_parser_terminal(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } for ( ;; ) { - token = njs_parser_property_expression(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; @@ -923,8 +918,6 @@ njs_parser_call_expression(njs_vm_t *vm, node = parser->node; if (token != NJS_TOKEN_OPEN_PARENTHESIS) { - /* TODO: var o = new Object; */ - node->ctor = ctor; return token; } @@ -937,19 +930,6 @@ njs_parser_call_expression(njs_vm_t *vm, + sizeof(njs_vmcode_function_call_t); break; - case NJS_TOKEN_FUNCTION_EXPRESSION: - func = njs_parser_node_alloc(vm); - if (nxt_slow_path(func == NULL)) { - return NJS_TOKEN_ERROR; - } - - func->token = NJS_TOKEN_FUNCTION_CALL; - func->left = node; - func->index = node->index; - parser->code_size += sizeof(njs_vmcode_function_frame_t) - + sizeof(njs_vmcode_function_call_t); - break; - case NJS_TOKEN_PROPERTY: func = njs_parser_node_alloc(vm); if (nxt_slow_path(func == NULL)) { @@ -964,6 +944,9 @@ njs_parser_call_expression(njs_vm_t *vm, default: /* + * NJS_TOKEN_METHOD_CALL, + * NJS_TOKEN_FUNCTION_CALL, + * NJS_TOKEN_FUNCTION_EXPRESSION, * NJS_TOKEN_OPEN_PARENTHESIS, * NJS_TOKEN_OBJECT_CONSTRUCTOR, * NJS_TOKEN_ARRAY_CONSTRUCTOR, @@ -986,6 +969,13 @@ njs_parser_call_expression(njs_vm_t *vm, break; } + func->ctor = 0; + + if (token != NJS_TOKEN_OPEN_PARENTHESIS) { + parser->node = func; + return token; + } + token = njs_parser_arguments(vm, parser, func); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; @@ -1002,6 +992,101 @@ njs_parser_call_expression(njs_vm_t *vm, static njs_token_t +njs_parser_new_expression(njs_vm_t *vm, njs_parser_t *parser, + njs_token_t token) +{ + njs_parser_node_t *func, *node; + + token = njs_parser_token(parser); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + if (token == NJS_TOKEN_NEW) { + token = njs_parser_new_expression(vm, parser, token); + + } else { + token = njs_parser_terminal(vm, parser, token); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + token = njs_parser_property_expression(vm, parser, token); + } + + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + node = parser->node; + + switch (node->token) { + + case NJS_TOKEN_NAME: + func = node; + func->token = NJS_TOKEN_FUNCTION_CALL; + parser->code_size += sizeof(njs_vmcode_function_frame_t) + + sizeof(njs_vmcode_function_call_t); + break; + + case NJS_TOKEN_PROPERTY: + func = njs_parser_node_alloc(vm); + if (nxt_slow_path(func == NULL)) { + return NJS_TOKEN_ERROR; + } + + func->token = NJS_TOKEN_METHOD_CALL; + func->left = node; + parser->code_size += sizeof(njs_vmcode_method_frame_t) + + sizeof(njs_vmcode_function_call_t); + break; + + default: + /* + * NJS_TOKEN_METHOD_CALL, + * NJS_TOKEN_FUNCTION_CALL, + * NJS_TOKEN_FUNCTION_EXPRESSION, + * NJS_TOKEN_OPEN_PARENTHESIS, + * NJS_TOKEN_OBJECT_CONSTRUCTOR, + * NJS_TOKEN_ARRAY_CONSTRUCTOR, + * NJS_TOKEN_BOOLEAN_CONSTRUCTOR, + * NJS_TOKEN_NUMBER_CONSTRUCTOR, + * NJS_TOKEN_STRING_CONSTRUCTOR, + * NJS_TOKEN_FUNCTION_CONSTRUCTOR, + * NJS_TOKEN_REGEXP_CONSTRUCTOR, + * NJS_TOKEN_EVAL. + */ + func = njs_parser_node_alloc(vm); + if (nxt_slow_path(func == NULL)) { + return NJS_TOKEN_ERROR; + } + + func->token = NJS_TOKEN_FUNCTION_CALL; + func->left = node; + parser->code_size += sizeof(njs_vmcode_function_frame_t) + + sizeof(njs_vmcode_function_call_t); + break; + } + + func->ctor = 1; + + if (token != NJS_TOKEN_OPEN_PARENTHESIS) { + parser->node = func; + return token; + } + + token = njs_parser_arguments(vm, parser, func); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + parser->node = func; + + return njs_parser_token(parser); +} + + +static njs_token_t njs_parser_property_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) { diff -r b3e83fa52345 -r 8c2cea409034 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Sep 30 14:11:27 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Sep 30 22:07:07 2016 +0300 @@ -3631,6 +3631,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("(function(x) { return x + 1 }(2))"), nxt_string("3") }, + { nxt_string("a = function() { return 1 }(); a"), + nxt_string("1") }, + { nxt_string("a = (function() { return 1 })(); a"), nxt_string("1") }, @@ -3777,6 +3780,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("function f() {}; f = f + 1; f"), nxt_string("[object Function]1") }, + { nxt_string("function a() { return 1 }" + "function b() { return a }" + "function c() { return b }" + "c()()()"), + nxt_string("1") }, + #if 0 { nxt_string("function f() {}; f += 1; f"), nxt_string("[object Function]1") }, @@ -3884,6 +3893,56 @@ static njs_unit_test_t njs_test[] = "o.constructor === F"), nxt_string("true") }, + { nxt_string("function F() { return Number }" + "var o = new (F())(5);" + "typeof o +' '+ o"), + nxt_string("object 5") }, + + { nxt_string("function F() { return Number }" + "var o = new (F());" + "typeof o +' '+ o"), + nxt_string("object 0") }, + + { nxt_string("var o = new function F() { return Number }()(5);" + "typeof o +' '+ o"), + nxt_string("number 5") }, + + { nxt_string("var o = new (function F() { return Number }())(5);" + "typeof o +' '+ o"), + nxt_string("object 5") }, + + { nxt_string("var o = new (new function F() { return Number }())(5);" + "typeof o +' '+ o"), + nxt_string("object 5") }, + + { nxt_string("var o = new new function F() { return Number }()(5);" + "typeof o +' '+ o"), + nxt_string("object 5") }, + + { nxt_string("var b; function F(x) { return {a:x} }" + "function G(y) { b = y; return F }" + "var o = new G(3)(5);" + "b + ' ' + o.a"), + nxt_string("3 5") }, + + { nxt_string("var b; function F(x) { return {a:x} }" + "function G(y) { b = y; return F }" + "var o = new (new G(3))(5);" + "b + ' ' + o.a"), + nxt_string("3 5") }, + + { nxt_string("var b; function F(x) { return {a:x} }" + "function G(y) { b = y; return F }" + "var o = new new G(3)(5);" + "b + ' ' + o.a"), + nxt_string("3 5") }, + + { nxt_string("var b; function F(x) { return {a:x} }" + "var g = { G: function (y) { b = y; return F } };" + "var o = new new g.G(3)(5);" + "b + ' ' + o.a"), + nxt_string("3 5") }, + { nxt_string("function a() { return function(x) { return x + 1 } }" "b = a(); b(2)"), nxt_string("3") }, @@ -4282,6 +4341,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("Boolean()"), nxt_string("false") }, + { nxt_string("new Boolean()"), + nxt_string("false") }, + + { nxt_string("new Boolean"), + nxt_string("false") }, + { nxt_string("Boolean(0)"), nxt_string("false") }, @@ -4306,6 +4371,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("typeof new Boolean(1)"), nxt_string("object") }, + { nxt_string("typeof new Boolean"), + nxt_string("object") }, + { nxt_string("Boolean.name"), nxt_string("Boolean") }, @@ -4345,6 +4413,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("Number()"), nxt_string("0") }, + { nxt_string("new Number()"), + nxt_string("0") }, + + { nxt_string("new Number"), + nxt_string("0") }, + { nxt_string("Number(123)"), nxt_string("123") }, @@ -4365,6 +4439,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("typeof new Number(1)"), nxt_string("object") }, + { nxt_string("typeof new Number"), + nxt_string("object") }, + { nxt_string("Number.name"), nxt_string("Number") }, @@ -4401,12 +4478,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("String()"), nxt_string("") }, + { nxt_string("new String()"), + nxt_string("") }, + + { nxt_string("new String"), + nxt_string("") }, + { nxt_string("String(123)"), nxt_string("123") }, { nxt_string("new String(123)"), nxt_string("123") }, + { nxt_string("new String(123).length"), + nxt_string("3") }, + + { nxt_string("new String(123).toString()"), + nxt_string("123") }, + { nxt_string("String([1,2,3])"), nxt_string("1,2,3") }, @@ -4427,6 +4516,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("typeof new String('abc')"), nxt_string("object") }, + { nxt_string("typeof new String"), + nxt_string("object") }, + { nxt_string("String.name"), nxt_string("String") }, @@ -4926,6 +5018,15 @@ static njs_unit_test_t njs_test[] = "Date.prototype.toJSON.call(o, 1)"), nxt_string("OK") }, + { nxt_string("var d = new Date; d.__proto__"), + nxt_string("Invalid Date") }, + + { nxt_string("var d = new Date(); d.__proto__"), + nxt_string("Invalid Date") }, + + { nxt_string("var d = new Date(); d.__proto__ === Date.prototype"), + nxt_string("true") }, + { nxt_string("Date.name"), nxt_string("Date") }, From xeioex at nginx.com Mon Oct 3 11:01:21 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Mon, 03 Oct 2016 11:01:21 +0000 Subject: [nginx] Resolver: introduced state field in ngx_resolver_srv_name_t. Message-ID: details: http://hg.nginx.org/nginx/rev/c3e3de6d2672 branches: changeset: 6714:c3e3de6d2672 user: Dmitry Volyntsev date: Thu Sep 29 19:40:47 2016 +0300 description: Resolver: introduced state field in ngx_resolver_srv_name_t. It keeps the actual state value of a DNS SRV subrequest and can be used to report a more detailed log for failed SRV records. diffstat: src/core/ngx_resolver.c | 1 + src/core/ngx_resolver.h | 1 + 2 files changed, 2 insertions(+), 0 deletions(-) diffs (22 lines): diff -r 63b8b157b776 -r c3e3de6d2672 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Thu Sep 29 18:06:05 2016 +0300 +++ b/src/core/ngx_resolver.c Thu Sep 29 19:40:47 2016 +0300 @@ -3006,6 +3006,7 @@ ngx_resolver_srv_names_handler(ngx_resol ctx->count--; srv->ctx = NULL; + srv->state = cctx->state; if (cctx->naddrs) { diff -r 63b8b157b776 -r c3e3de6d2672 src/core/ngx_resolver.h --- a/src/core/ngx_resolver.h Thu Sep 29 18:06:05 2016 +0300 +++ b/src/core/ngx_resolver.h Thu Sep 29 19:40:47 2016 +0300 @@ -82,6 +82,7 @@ typedef struct { u_short port; ngx_resolver_ctx_t *ctx; + ngx_int_t state; ngx_uint_t naddrs; ngx_addr_t *addrs; From lstewart at netflix.com Mon Oct 3 12:36:19 2016 From: lstewart at netflix.com (Lawrence Stewart) Date: Mon, 3 Oct 2016 23:36:19 +1100 Subject: Inconsistent order for ngx_destroy_pool() and ngx_close_connection() In-Reply-To: <20161003074553.GI8172@lo0.su> References: <20161003074553.GI8172@lo0.su> Message-ID: Hi Ruslan, On Mon, Oct 3, 2016 at 6:45 PM, Ruslan Ermilov wrote: > On Mon, Oct 03, 2016 at 03:37:38PM +1100, Lawrence Stewart wrote: > > Hi all, > > > > I need to pull kernel data using getsockopt() for a connection prior to > the > > socket being closed. A pool cleanup handler registered with the > > ngx_connection_t's pool would seem to be the right way to do this, but > > ngx_http_close_connection() calls ngx_close_connection() prior to > > ngx_destroy_pool(), which means my cleanup handler sees a closed socket. > > > > A look through ngx_close_connection() and the functions it calls would > lead > > me to believe it should be safe (and possible even desirable in an > ordering > > sense) to destroy the connection's pool prior to calling > > ngx_close_connection(). > > If we talk about client connections, then c->log is allocated from > c->pool, and c->read->log and c->write->log also use this log object, > see ngx_event_accept(). > > A look through ngx_close_connection() shows that nearly every call > it makes: ngx_log_error, ngx_del_timer, ngx_del_conn, ngx_del_event, > ngx_delete_posted_event, and ngx_reusable_connection need c->log > which would be destroyed if c->pool was destroyed. > Thanks, I missed this log allocation detail. > > > There is an existence proof in the nginx tree that > > this is reasonable to do (see [1]) and there is also a comment in > > ngx_close_connection() that implies it expects that the connection's pool > > has already been destroyed i.e. > > > > /* we use ngx_cycle->log because c->log was in c->pool */ > > This comment seems outdated since rev. c52408583801 which removed > the ngx_destroy_pool(c->pool) call from ngx_close_connection(): > > Ah, ok. > : @@ -388,8 +387,6 @@ void ngx_close_connection(ngx_connection > : c->fd = (ngx_socket_t) -1; > : c->data = NULL; > : > : - ngx_destroy_pool(c->pool); > : - > : if (ngx_close_socket(fd) == -1) { > : > : /* we use ngx_cycle->log because c->log was in c->pool */ > > > Are there some subtleties I'm missing, or is it correct and reasonable to > > always call ngx_destroy_pool() on a connection's pool prior to calling > > ngx_close_connection()? > > On the contrary, the upstream connection's pool is destroyed > before calling ngx_close_connection(), see ngx_http_upstream_next() > and ngx_http_upstream_finalize_request(). This is safe because > the upstream connection reuses the client connection's log, see > ngx_http_upstream_connect(). > Ah, I missed this detail too. Thanks for the pointer. So given that my idea is a fail, what is the recommended way to hook connection tear down from a module so that I can achieve my goal? Cheers, Lawrence -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Mon Oct 3 13:00:15 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 03 Oct 2016 13:00:15 +0000 Subject: [nginx] Introduced the NGX_COMPAT macro. Message-ID: details: http://hg.nginx.org/nginx/rev/d200a0fd00b7 branches: changeset: 6715:d200a0fd00b7 user: Ruslan Ermilov date: Thu Sep 29 15:28:24 2016 +0300 description: Introduced the NGX_COMPAT macro. When enabled, some structures are padded to be size compatible with their NGINX Plus versions. diffstat: src/core/ngx_config.h | 13 +++++++++++++ src/core/ngx_module.h | 8 +++++++- src/event/ngx_event_connect.h | 3 +++ src/http/ngx_http_upstream.h | 9 +++++++++ src/http/ngx_http_upstream_round_robin.h | 3 +++ src/stream/ngx_stream_upstream.h | 3 +++ src/stream/ngx_stream_upstream_round_robin.h | 3 +++ 7 files changed, 41 insertions(+), 1 deletions(-) diffs (131 lines): diff -r c3e3de6d2672 -r d200a0fd00b7 src/core/ngx_config.h --- a/src/core/ngx_config.h Thu Sep 29 19:40:47 2016 +0300 +++ b/src/core/ngx_config.h Thu Sep 29 15:28:24 2016 +0300 @@ -129,4 +129,17 @@ typedef intptr_t ngx_flag_t; #define NGX_MAX_INT32_VALUE (uint32_t) 0x7fffffff +#if (NGX_COMPAT) + +#define NGX_COMPAT_BEGIN(slots) uint64_t spare[slots]; +#define NGX_COMPAT_END + +#else + +#define NGX_COMPAT_BEGIN(slots) +#define NGX_COMPAT_END + +#endif + + #endif /* _NGX_CONFIG_H_INCLUDED_ */ diff -r c3e3de6d2672 -r d200a0fd00b7 src/core/ngx_module.h --- a/src/core/ngx_module.h Thu Sep 29 19:40:47 2016 +0300 +++ b/src/core/ngx_module.h Thu Sep 29 15:28:24 2016 +0300 @@ -212,6 +212,12 @@ #define NGX_MODULE_SIGNATURE_33 "0" #endif +#if (NGX_COMPAT) +#define NGX_MODULE_SIGNATURE_34 "1" +#else +#define NGX_MODULE_SIGNATURE_34 "0" +#endif + #define NGX_MODULE_SIGNATURE \ NGX_MODULE_SIGNATURE_0 NGX_MODULE_SIGNATURE_1 NGX_MODULE_SIGNATURE_2 \ NGX_MODULE_SIGNATURE_3 NGX_MODULE_SIGNATURE_4 NGX_MODULE_SIGNATURE_5 \ @@ -224,7 +230,7 @@ NGX_MODULE_SIGNATURE_24 NGX_MODULE_SIGNATURE_25 NGX_MODULE_SIGNATURE_26 \ NGX_MODULE_SIGNATURE_27 NGX_MODULE_SIGNATURE_28 NGX_MODULE_SIGNATURE_29 \ NGX_MODULE_SIGNATURE_30 NGX_MODULE_SIGNATURE_31 NGX_MODULE_SIGNATURE_32 \ - NGX_MODULE_SIGNATURE_33 + NGX_MODULE_SIGNATURE_33 NGX_MODULE_SIGNATURE_34 #define NGX_MODULE_V1 \ diff -r c3e3de6d2672 -r d200a0fd00b7 src/event/ngx_event_connect.h --- a/src/event/ngx_event_connect.h Thu Sep 29 19:40:47 2016 +0300 +++ b/src/event/ngx_event_connect.h Thu Sep 29 15:28:24 2016 +0300 @@ -68,6 +68,9 @@ struct ngx_peer_connection_s { /* ngx_connection_log_error_e */ unsigned log_error:2; + + NGX_COMPAT_BEGIN(2) + NGX_COMPAT_END }; diff -r c3e3de6d2672 -r d200a0fd00b7 src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Thu Sep 29 19:40:47 2016 +0300 +++ b/src/http/ngx_http_upstream.h Thu Sep 29 15:28:24 2016 +0300 @@ -102,6 +102,9 @@ typedef struct { unsigned down:1; unsigned backup:1; + + NGX_COMPAT_BEGIN(6) + NGX_COMPAT_END } ngx_http_upstream_server_t; @@ -229,6 +232,9 @@ typedef struct { #endif ngx_str_t module; + + NGX_COMPAT_BEGIN(2) + NGX_COMPAT_END } ngx_http_upstream_conf_t; @@ -382,6 +388,9 @@ struct ngx_http_upstream_s { unsigned request_sent:1; unsigned request_body_sent:1; unsigned header_sent:1; + + NGX_COMPAT_BEGIN(1) + NGX_COMPAT_END }; diff -r c3e3de6d2672 -r d200a0fd00b7 src/http/ngx_http_upstream_round_robin.h --- a/src/http/ngx_http_upstream_round_robin.h Thu Sep 29 19:40:47 2016 +0300 +++ b/src/http/ngx_http_upstream_round_robin.h Thu Sep 29 15:28:24 2016 +0300 @@ -50,6 +50,9 @@ struct ngx_http_upstream_rr_peer_s { #endif ngx_http_upstream_rr_peer_t *next; + + NGX_COMPAT_BEGIN(32) + NGX_COMPAT_END }; diff -r c3e3de6d2672 -r d200a0fd00b7 src/stream/ngx_stream_upstream.h --- a/src/stream/ngx_stream_upstream.h Thu Sep 29 19:40:47 2016 +0300 +++ b/src/stream/ngx_stream_upstream.h Thu Sep 29 15:28:24 2016 +0300 @@ -58,6 +58,9 @@ typedef struct { unsigned down:1; unsigned backup:1; + + NGX_COMPAT_BEGIN(4) + NGX_COMPAT_END } ngx_stream_upstream_server_t; diff -r c3e3de6d2672 -r d200a0fd00b7 src/stream/ngx_stream_upstream_round_robin.h --- a/src/stream/ngx_stream_upstream_round_robin.h Thu Sep 29 19:40:47 2016 +0300 +++ b/src/stream/ngx_stream_upstream_round_robin.h Thu Sep 29 15:28:24 2016 +0300 @@ -50,6 +50,9 @@ struct ngx_stream_upstream_rr_peer_s { #endif ngx_stream_upstream_rr_peer_t *next; + + NGX_COMPAT_BEGIN(25) + NGX_COMPAT_END }; From ru at nginx.com Mon Oct 3 13:00:17 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 03 Oct 2016 13:00:17 +0000 Subject: [nginx] Modules compatibility: --with-compat configure option. Message-ID: details: http://hg.nginx.org/nginx/rev/57c8e12c460c branches: changeset: 6716:57c8e12c460c user: Maxim Dounin date: Mon Oct 03 15:58:16 2016 +0300 description: Modules compatibility: --with-compat configure option. diffstat: auto/modules | 12 ++++++++++++ auto/options | 6 ++++++ 2 files changed, 18 insertions(+), 0 deletions(-) diffs (52 lines): diff -r d200a0fd00b7 -r 57c8e12c460c auto/modules --- a/auto/modules Thu Sep 29 15:28:24 2016 +0300 +++ b/auto/modules Mon Oct 03 15:58:16 2016 +0300 @@ -1312,6 +1312,18 @@ fi modules="$modules $MISC_MODULES" +if [ $NGX_COMPAT = YES ]; then + have=NGX_COMPAT . auto/have + have=NGX_HTTP_GZIP . auto/have + have=NGX_HTTP_DAV . auto/have + have=NGX_HTTP_REALIP . auto/have + have=NGX_HTTP_X_FORWARDED_FOR . auto/have + have=NGX_HTTP_HEADERS . auto/have + have=NGX_HTTP_UPSTREAM_ZONE . auto/have + have=NGX_STREAM_UPSTREAM_ZONE . auto/have +fi + + cat << END > $NGX_MODULES_C #include diff -r d200a0fd00b7 -r 57c8e12c460c auto/options --- a/auto/options Thu Sep 29 15:28:24 2016 +0300 +++ b/auto/options Mon Oct 03 15:58:16 2016 +0300 @@ -134,6 +134,8 @@ NGX_ADDONS= NGX_ADDON_DEPS= DYNAMIC_ADDONS= +NGX_COMPAT=NO + USE_PCRE=NO PCRE=NONE PCRE_OPT= @@ -325,6 +327,8 @@ use the \"--with-mail_ssl_module\" optio --add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;; --add-dynamic-module=*) DYNAMIC_ADDONS="$DYNAMIC_ADDONS $value" ;; + --with-compat) NGX_COMPAT=YES ;; + --with-cc=*) CC="$value" ;; --with-cpp=*) CPP="$value" ;; --with-cc-opt=*) NGX_CC_OPT="$value" ;; @@ -532,6 +536,8 @@ cat << END --add-module=PATH enable external module --add-dynamic-module=PATH enable dynamic external module + --with-compat dynamic modules compatibility + --with-cc=PATH set C compiler pathname --with-cpp=PATH set C preprocessor pathname --with-cc-opt=OPTIONS set additional C compiler options From ru at nginx.com Mon Oct 3 13:00:20 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 03 Oct 2016 13:00:20 +0000 Subject: [nginx] Modules compatibility: degradation fields now always present. Message-ID: details: http://hg.nginx.org/nginx/rev/3b522d7a5b34 branches: changeset: 6717:3b522d7a5b34 user: Maxim Dounin date: Mon Oct 03 15:58:19 2016 +0300 description: Modules compatibility: degradation fields now always present. There is no need to save these two bits as they are wasted anyway. Removed NGX_HTTP_DEGRADATION from the signature accordingly. diffstat: src/core/ngx_module.h | 4 ---- src/http/ngx_http_core_module.h | 2 -- 2 files changed, 0 insertions(+), 6 deletions(-) diffs (29 lines): diff -r 57c8e12c460c -r 3b522d7a5b34 src/core/ngx_module.h --- a/src/core/ngx_module.h Mon Oct 03 15:58:16 2016 +0300 +++ b/src/core/ngx_module.h Mon Oct 03 15:58:19 2016 +0300 @@ -170,11 +170,7 @@ #define NGX_MODULE_SIGNATURE_26 "0" #endif -#if (NGX_HTTP_DEGRADATION) #define NGX_MODULE_SIGNATURE_27 "1" -#else -#define NGX_MODULE_SIGNATURE_27 "0" -#endif #if (NGX_HTTP_X_FORWARDED_FOR) #define NGX_MODULE_SIGNATURE_28 "1" diff -r 57c8e12c460c -r 3b522d7a5b34 src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Mon Oct 03 15:58:16 2016 +0300 +++ b/src/http/ngx_http_core_module.h Mon Oct 03 15:58:19 2016 +0300 @@ -327,10 +327,8 @@ struct ngx_http_core_loc_conf_s { unsigned auto_redirect:1; #if (NGX_HTTP_GZIP) unsigned gzip_disable_msie6:2; -#if (NGX_HTTP_DEGRADATION) unsigned gzip_disable_degradation:2; #endif -#endif ngx_http_location_tree_node_t *static_locations; #if (NGX_PCRE) From ru at nginx.com Mon Oct 3 13:00:22 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 03 Oct 2016 13:00:22 +0000 Subject: [nginx] Modules compatibility: http2. Message-ID: details: http://hg.nginx.org/nginx/rev/bdf64ae3376b branches: changeset: 6718:bdf64ae3376b user: Maxim Dounin date: Mon Oct 03 15:58:22 2016 +0300 description: Modules compatibility: http2. HTTP/2-specific fields in structures are now available unconditionally. Removed NGX_HTTP_V2 from the signature accordingly. diffstat: src/core/ngx_module.h | 4 ---- src/http/ngx_http.h | 3 --- src/http/ngx_http_core_module.h | 4 ---- src/http/ngx_http_request.h | 4 ---- 4 files changed, 0 insertions(+), 15 deletions(-) diffs (75 lines): diff -r 3b522d7a5b34 -r bdf64ae3376b src/core/ngx_module.h --- a/src/core/ngx_module.h Mon Oct 03 15:58:19 2016 +0300 +++ b/src/core/ngx_module.h Mon Oct 03 15:58:22 2016 +0300 @@ -158,11 +158,7 @@ #define NGX_MODULE_SIGNATURE_24 "0" #endif -#if (NGX_HTTP_V2) #define NGX_MODULE_SIGNATURE_25 "1" -#else -#define NGX_MODULE_SIGNATURE_25 "0" -#endif #if (NGX_HTTP_GZIP) #define NGX_MODULE_SIGNATURE_26 "1" diff -r 3b522d7a5b34 -r bdf64ae3376b src/http/ngx_http.h --- a/src/http/ngx_http.h Mon Oct 03 15:58:19 2016 +0300 +++ b/src/http/ngx_http.h Mon Oct 03 15:58:22 2016 +0300 @@ -19,10 +19,7 @@ typedef struct ngx_http_cache_s ng typedef struct ngx_http_file_cache_s ngx_http_file_cache_t; typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t; typedef struct ngx_http_chunked_s ngx_http_chunked_t; - -#if (NGX_HTTP_V2) typedef struct ngx_http_v2_stream_s ngx_http_v2_stream_t; -#endif typedef ngx_int_t (*ngx_http_header_handler_pt)(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); diff -r 3b522d7a5b34 -r bdf64ae3376b src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Mon Oct 03 15:58:19 2016 +0300 +++ b/src/http/ngx_http_core_module.h Mon Oct 03 15:58:22 2016 +0300 @@ -68,9 +68,7 @@ typedef struct { #if (NGX_HTTP_SSL) unsigned ssl:1; #endif -#if (NGX_HTTP_V2) unsigned http2:1; -#endif #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:1; #endif @@ -237,9 +235,7 @@ struct ngx_http_addr_conf_s { #if (NGX_HTTP_SSL) unsigned ssl:1; #endif -#if (NGX_HTTP_V2) unsigned http2:1; -#endif unsigned proxy_protocol:1; }; diff -r 3b522d7a5b34 -r bdf64ae3376b src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Mon Oct 03 15:58:19 2016 +0300 +++ b/src/http/ngx_http_request.h Mon Oct 03 15:58:22 2016 +0300 @@ -286,9 +286,7 @@ typedef struct { ngx_chain_t *bufs; ngx_buf_t *buf; off_t rest; -#if (NGX_HTTP_V2) off_t received; -#endif ngx_chain_t *free; ngx_chain_t *busy; ngx_http_chunked_t *chunked; @@ -438,9 +436,7 @@ struct ngx_http_request_s { ngx_uint_t err_status; ngx_http_connection_t *http_connection; -#if (NGX_HTTP_V2) ngx_http_v2_stream_t *stream; -#endif ngx_http_log_handler_pt log_handler; From ru at nginx.com Mon Oct 3 13:00:25 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 03 Oct 2016 13:00:25 +0000 Subject: [nginx] Modules compatibility: removed unneeded IPV6_V6ONLY checks. Message-ID: details: http://hg.nginx.org/nginx/rev/cebf5fed00bf branches: changeset: 6719:cebf5fed00bf user: Maxim Dounin date: Mon Oct 03 15:58:25 2016 +0300 description: Modules compatibility: removed unneeded IPV6_V6ONLY checks. The IPV6_V6ONLY macro is now checked only while parsing appropriate flag and when using the macro. The ipv6only field in listen structures is always initialized to 1, even if not supported on a given platform. This is expected to prevent a module compiled without IPV6_V6ONLY from accidentally creating dual sockets if loaded into main binary with proper IPV6_V6ONLY support. diffstat: src/core/ngx_connection.h | 2 +- src/core/ngx_module.h | 4 - src/http/ngx_http.c | 134 ++++++++++++++++++------------------ src/http/ngx_http_core_module.c | 2 +- src/http/ngx_http_core_module.h | 2 +- src/mail/ngx_mail.c | 2 +- src/mail/ngx_mail.h | 2 +- src/mail/ngx_mail_core_module.c | 2 +- src/stream/ngx_stream.c | 2 +- src/stream/ngx_stream.h | 2 +- src/stream/ngx_stream_core_module.c | 2 +- 11 files changed, 76 insertions(+), 80 deletions(-) diffs (281 lines): diff -r bdf64ae3376b -r cebf5fed00bf src/core/ngx_connection.h --- a/src/core/ngx_connection.h Mon Oct 03 15:58:22 2016 +0300 +++ b/src/core/ngx_connection.h Mon Oct 03 15:58:25 2016 +0300 @@ -66,7 +66,7 @@ struct ngx_listening_s { unsigned addr_ntop:1; unsigned wildcard:1; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif #if (NGX_HAVE_REUSEPORT) diff -r bdf64ae3376b -r cebf5fed00bf src/core/ngx_module.h --- a/src/core/ngx_module.h Mon Oct 03 15:58:22 2016 +0300 +++ b/src/core/ngx_module.h Mon Oct 03 15:58:25 2016 +0300 @@ -71,11 +71,7 @@ #define NGX_MODULE_SIGNATURE_8 "0" #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) #define NGX_MODULE_SIGNATURE_9 "1" -#else -#define NGX_MODULE_SIGNATURE_9 "0" -#endif #if (NGX_HAVE_REUSEPORT) #define NGX_MODULE_SIGNATURE_10 "1" diff -r bdf64ae3376b -r cebf5fed00bf src/http/ngx_http.c --- a/src/http/ngx_http.c Mon Oct 03 15:58:22 2016 +0300 +++ b/src/http/ngx_http.c Mon Oct 03 15:58:25 2016 +0300 @@ -1756,7 +1756,7 @@ ngx_http_add_listening(ngx_conf_t *cf, n ls->deferred_accept = addr->opt.deferred_accept; #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = addr->opt.ipv6only; #endif @@ -1824,72 +1824,7 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h return NGX_ERROR; } - addrs[i].conf.virtual_names = vn; - - vn->names.hash = addr[i].hash; - vn->names.wc_head = addr[i].wc_head; - vn->names.wc_tail = addr[i].wc_tail; -#if (NGX_PCRE) - vn->nregex = addr[i].nregex; - vn->regex = addr[i].regex; -#endif - } - - return NGX_OK; -} - - -#if (NGX_HAVE_INET6) - -static ngx_int_t -ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport, - ngx_http_conf_addr_t *addr) -{ - ngx_uint_t i; - ngx_http_in6_addr_t *addrs6; - struct sockaddr_in6 *sin6; - ngx_http_virtual_names_t *vn; - - hport->addrs = ngx_pcalloc(cf->pool, - hport->naddrs * sizeof(ngx_http_in6_addr_t)); - if (hport->addrs == NULL) { - return NGX_ERROR; - } - - addrs6 = hport->addrs; - - for (i = 0; i < hport->naddrs; i++) { - - sin6 = &addr[i].opt.sockaddr.sockaddr_in6; - addrs6[i].addr6 = sin6->sin6_addr; - addrs6[i].conf.default_server = addr[i].default_server; -#if (NGX_HTTP_SSL) - addrs6[i].conf.ssl = addr[i].opt.ssl; -#endif -#if (NGX_HTTP_V2) - addrs6[i].conf.http2 = addr[i].opt.http2; -#endif - addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol; - - if (addr[i].hash.buckets == NULL - && (addr[i].wc_head == NULL - || addr[i].wc_head->hash.buckets == NULL) - && (addr[i].wc_tail == NULL - || addr[i].wc_tail->hash.buckets == NULL) -#if (NGX_PCRE) - && addr[i].nregex == 0 -#endif - ) - { - continue; - } - - vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t)); - if (vn == NULL) { - return NGX_ERROR; - } - - addrs6[i].conf.virtual_names = vn; + addrs[i].conf.virtual_names = vn; vn->names.hash = addr[i].hash; vn->names.wc_head = addr[i].wc_head; @@ -1903,6 +1838,71 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_ return NGX_OK; } + +#if (NGX_HAVE_INET6) + +static ngx_int_t +ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport, + ngx_http_conf_addr_t *addr) +{ + ngx_uint_t i; + ngx_http_in6_addr_t *addrs6; + struct sockaddr_in6 *sin6; + ngx_http_virtual_names_t *vn; + + hport->addrs = ngx_pcalloc(cf->pool, + hport->naddrs * sizeof(ngx_http_in6_addr_t)); + if (hport->addrs == NULL) { + return NGX_ERROR; + } + + addrs6 = hport->addrs; + + for (i = 0; i < hport->naddrs; i++) { + + sin6 = &addr[i].opt.sockaddr.sockaddr_in6; + addrs6[i].addr6 = sin6->sin6_addr; + addrs6[i].conf.default_server = addr[i].default_server; +#if (NGX_HTTP_SSL) + addrs6[i].conf.ssl = addr[i].opt.ssl; +#endif +#if (NGX_HTTP_V2) + addrs6[i].conf.http2 = addr[i].opt.http2; +#endif + addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol; + + if (addr[i].hash.buckets == NULL + && (addr[i].wc_head == NULL + || addr[i].wc_head->hash.buckets == NULL) + && (addr[i].wc_tail == NULL + || addr[i].wc_tail->hash.buckets == NULL) +#if (NGX_PCRE) + && addr[i].nregex == 0 +#endif + ) + { + continue; + } + + vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t)); + if (vn == NULL) { + return NGX_ERROR; + } + + addrs6[i].conf.virtual_names = vn; + + vn->names.hash = addr[i].hash; + vn->names.wc_head = addr[i].wc_head; + vn->names.wc_tail = addr[i].wc_tail; +#if (NGX_PCRE) + vn->nregex = addr[i].nregex; + vn->regex = addr[i].regex; +#endif + } + + return NGX_OK; +} + #endif diff -r bdf64ae3376b -r cebf5fed00bf src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Mon Oct 03 15:58:22 2016 +0300 +++ b/src/http/ngx_http_core_module.c Mon Oct 03 15:58:25 2016 +0300 @@ -3939,7 +3939,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx lsopt.fastopen = -1; #endif lsopt.wildcard = u.wildcard; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) lsopt.ipv6only = 1; #endif diff -r bdf64ae3376b -r cebf5fed00bf src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Mon Oct 03 15:58:22 2016 +0300 +++ b/src/http/ngx_http_core_module.h Mon Oct 03 15:58:25 2016 +0300 @@ -69,7 +69,7 @@ typedef struct { unsigned ssl:1; #endif unsigned http2:1; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif #if (NGX_HAVE_REUSEPORT) diff -r bdf64ae3376b -r cebf5fed00bf src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c Mon Oct 03 15:58:22 2016 +0300 +++ b/src/mail/ngx_mail.c Mon Oct 03 15:58:25 2016 +0300 @@ -341,7 +341,7 @@ ngx_mail_optimize_servers(ngx_conf_t *cf ls->keepcnt = addr[i].opt.tcp_keepcnt; #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = addr[i].opt.ipv6only; #endif diff -r bdf64ae3376b -r cebf5fed00bf src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Mon Oct 03 15:58:22 2016 +0300 +++ b/src/mail/ngx_mail.h Mon Oct 03 15:58:25 2016 +0300 @@ -38,7 +38,7 @@ typedef struct { #if (NGX_MAIL_SSL) unsigned ssl:1; #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif unsigned so_keepalive:2; diff -r bdf64ae3376b -r cebf5fed00bf src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c Mon Oct 03 15:58:22 2016 +0300 +++ b/src/mail/ngx_mail_core_module.c Mon Oct 03 15:58:25 2016 +0300 @@ -353,7 +353,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx ls->wildcard = u.wildcard; ls->ctx = cf->ctx; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = 1; #endif diff -r bdf64ae3376b -r cebf5fed00bf src/stream/ngx_stream.c --- a/src/stream/ngx_stream.c Mon Oct 03 15:58:22 2016 +0300 +++ b/src/stream/ngx_stream.c Mon Oct 03 15:58:25 2016 +0300 @@ -506,7 +506,7 @@ ngx_stream_optimize_servers(ngx_conf_t * ls->keepcnt = addr[i].opt.tcp_keepcnt; #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = addr[i].opt.ipv6only; #endif diff -r bdf64ae3376b -r cebf5fed00bf src/stream/ngx_stream.h --- a/src/stream/ngx_stream.h Mon Oct 03 15:58:22 2016 +0300 +++ b/src/stream/ngx_stream.h Mon Oct 03 15:58:25 2016 +0300 @@ -52,7 +52,7 @@ typedef struct { #if (NGX_STREAM_SSL) unsigned ssl:1; #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif #if (NGX_HAVE_REUSEPORT) diff -r bdf64ae3376b -r cebf5fed00bf src/stream/ngx_stream_core_module.c --- a/src/stream/ngx_stream_core_module.c Mon Oct 03 15:58:22 2016 +0300 +++ b/src/stream/ngx_stream_core_module.c Mon Oct 03 15:58:25 2016 +0300 @@ -624,7 +624,7 @@ ngx_stream_core_listen(ngx_conf_t *cf, n ls->wildcard = u.wildcard; ls->ctx = cf->ctx; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = 1; #endif From ru at nginx.com Mon Oct 3 13:00:27 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 03 Oct 2016 13:00:27 +0000 Subject: [nginx] Modules compatibility: removed unneeded NGX_HAVE_REUSEPORT checks. Message-ID: details: http://hg.nginx.org/nginx/rev/9170240f1241 branches: changeset: 6720:9170240f1241 user: Maxim Dounin date: Mon Oct 03 15:58:29 2016 +0300 description: Modules compatibility: removed unneeded NGX_HAVE_REUSEPORT checks. Removed NGX_HAVE_REUSEPORT from the signature accordingly. diffstat: src/core/ngx_connection.h | 2 -- src/core/ngx_module.h | 5 ----- src/http/ngx_http_core_module.h | 2 -- src/stream/ngx_stream.h | 2 -- 4 files changed, 0 insertions(+), 11 deletions(-) diffs (56 lines): diff -r cebf5fed00bf -r 9170240f1241 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Mon Oct 03 15:58:25 2016 +0300 +++ b/src/core/ngx_connection.h Mon Oct 03 15:58:29 2016 +0300 @@ -69,10 +69,8 @@ struct ngx_listening_s { #if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif -#if (NGX_HAVE_REUSEPORT) unsigned reuseport:1; unsigned add_reuseport:1; -#endif unsigned keepalive:2; #if (NGX_HAVE_DEFERRED_ACCEPT) diff -r cebf5fed00bf -r 9170240f1241 src/core/ngx_module.h --- a/src/core/ngx_module.h Mon Oct 03 15:58:25 2016 +0300 +++ b/src/core/ngx_module.h Mon Oct 03 15:58:29 2016 +0300 @@ -72,12 +72,7 @@ #endif #define NGX_MODULE_SIGNATURE_9 "1" - -#if (NGX_HAVE_REUSEPORT) #define NGX_MODULE_SIGNATURE_10 "1" -#else -#define NGX_MODULE_SIGNATURE_10 "0" -#endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) #define NGX_MODULE_SIGNATURE_11 "1" diff -r cebf5fed00bf -r 9170240f1241 src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Mon Oct 03 15:58:25 2016 +0300 +++ b/src/http/ngx_http_core_module.h Mon Oct 03 15:58:29 2016 +0300 @@ -72,9 +72,7 @@ typedef struct { #if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif -#if (NGX_HAVE_REUSEPORT) unsigned reuseport:1; -#endif unsigned so_keepalive:2; unsigned proxy_protocol:1; diff -r cebf5fed00bf -r 9170240f1241 src/stream/ngx_stream.h --- a/src/stream/ngx_stream.h Mon Oct 03 15:58:25 2016 +0300 +++ b/src/stream/ngx_stream.h Mon Oct 03 15:58:29 2016 +0300 @@ -55,9 +55,7 @@ typedef struct { #if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif -#if (NGX_HAVE_REUSEPORT) unsigned reuseport:1; -#endif unsigned so_keepalive:2; unsigned proxy_protocol:1; #if (NGX_HAVE_KEEPALIVE_TUNABLE) From ru at nginx.com Mon Oct 3 13:00:30 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 03 Oct 2016 13:00:30 +0000 Subject: [nginx] Modules compatibility: removed two NGX_HAVE_DEFERRED_ACCEPT checks. Message-ID: details: http://hg.nginx.org/nginx/rev/48bab8b83f4e branches: changeset: 6721:48bab8b83f4e user: Ruslan Ermilov date: Mon Oct 03 15:58:30 2016 +0300 description: Modules compatibility: removed two NGX_HAVE_DEFERRED_ACCEPT checks. Removed (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) from the signature accordingly. diffstat: src/core/ngx_connection.h | 4 +--- src/core/ngx_module.h | 4 ---- src/http/ngx_http_core_module.h | 4 +--- 3 files changed, 2 insertions(+), 10 deletions(-) diffs (55 lines): diff -r 9170240f1241 -r 48bab8b83f4e src/core/ngx_connection.h --- a/src/core/ngx_connection.h Mon Oct 03 15:58:29 2016 +0300 +++ b/src/core/ngx_connection.h Mon Oct 03 15:58:30 2016 +0300 @@ -73,14 +73,12 @@ struct ngx_listening_s { unsigned add_reuseport:1; unsigned keepalive:2; -#if (NGX_HAVE_DEFERRED_ACCEPT) unsigned deferred_accept:1; unsigned delete_deferred:1; unsigned add_deferred:1; -#ifdef SO_ACCEPTFILTER +#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) char *accept_filter; #endif -#endif #if (NGX_HAVE_SETFIB) int setfib; #endif diff -r 9170240f1241 -r 48bab8b83f4e src/core/ngx_module.h --- a/src/core/ngx_module.h Mon Oct 03 15:58:29 2016 +0300 +++ b/src/core/ngx_module.h Mon Oct 03 15:58:30 2016 +0300 @@ -80,11 +80,7 @@ #define NGX_MODULE_SIGNATURE_11 "0" #endif -#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) #define NGX_MODULE_SIGNATURE_12 "1" -#else -#define NGX_MODULE_SIGNATURE_12 "0" -#endif #if (NGX_HAVE_SETFIB) #define NGX_MODULE_SIGNATURE_13 "1" diff -r 9170240f1241 -r 48bab8b83f4e src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Mon Oct 03 15:58:29 2016 +0300 +++ b/src/http/ngx_http_core_module.h Mon Oct 03 15:58:30 2016 +0300 @@ -72,6 +72,7 @@ typedef struct { #if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif + unsigned deferred_accept:1; unsigned reuseport:1; unsigned so_keepalive:2; unsigned proxy_protocol:1; @@ -94,9 +95,6 @@ typedef struct { #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) char *accept_filter; #endif -#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) - ngx_uint_t deferred_accept; -#endif u_char addr[NGX_SOCKADDR_STRLEN + 1]; } ngx_http_listen_opt_t; From mdounin at mdounin.ru Mon Oct 3 17:38:22 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 3 Oct 2016 20:38:22 +0300 Subject: [PATCH] Upstream: fix warning when building with BoringSSL In-Reply-To: References: <8c3706ffdc9bde38ef50.1475071847@mandy.local> Message-ID: <20161003173822.GF73038@mdounin.ru> Hello! On Fri, Sep 30, 2016 at 05:50:27AM -0700, Piotr Sikora wrote: > Hey Alessandro, > > > # HG changeset patch > > # User Alessandro Ghedini > > # Date 1475070884 -3600 > > # Wed Sep 28 14:54:44 2016 +0100 > > # Node ID fe7d9e3987d40f16d86fd01d94ad16ff58467af2 > > # Parent 29bf0dbc0a77914bc94bd001a2b17d364e8e50d9 > > Upstream: fix warning when building with BoringSSL > > > > BoringSSL takes a const u_char * for SSL_set_tlsext_host_name but > > OpenSSL only takes a u_char *. Since NGINX is built with -Werror by > > default this breaks the build. > > You need to apply the same fix to ngx_stream_proxy_module.c. > > btw: I've sent exactly the same patch in the past, so good luck: > http://mailman.nginx.org/pipermail/nginx-devel/2015-November/007499.html I have no strong objections, but the patch as you've submitted casts to "const char *", while just "char *" should be enough. And BoringSSL still fails to build on FreeBSD out of the box (not to mention it now requires Go for building), which makes it non-trivial to test BoringSSL-related changes. Unless there are objections, I'm going to commit the patch below which adds (char *) casts. # HG changeset patch # User Maxim Dounin # Date 1475515513 -10800 # Mon Oct 03 20:25:13 2016 +0300 # Node ID 9984d19e3990b662045617f60ea0fa500d8d6afb # Parent 08b6836c9299942d642bd60442c7e58aee6356dc SSL: compatibility with BoringSSL. BoringSSL changed SSL_set_tlsext_host_name() to be a real function with a (const char *) argument, so it now triggers a warning due to conversion from (u_char *). Added an explicit cast to silence the warning. Prodded by Piotr Sikora, Alessandro Ghedini. diff -r 08b6836c9299 -r 9984d19e3990 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Jun 27 15:00:06 2016 -0700 +++ b/src/http/ngx_http_upstream.c Mon Oct 03 20:25:13 2016 +0300 @@ -1690,7 +1690,10 @@ ngx_http_upstream_ssl_name(ngx_http_requ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upstream SSL server name: \"%s\"", name.data); - if (SSL_set_tlsext_host_name(c->ssl->connection, name.data) == 0) { + if (SSL_set_tlsext_host_name(c->ssl->connection, + (char *) name.data) + == 0) + { ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, "SSL_set_tlsext_host_name(\"%s\") failed", name.data); return NGX_ERROR; diff -r 08b6836c9299 -r 9984d19e3990 src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Mon Jun 27 15:00:06 2016 -0700 +++ b/src/stream/ngx_stream_proxy_module.c Mon Oct 03 20:25:13 2016 +0300 @@ -948,7 +948,8 @@ ngx_stream_proxy_ssl_name(ngx_stream_ses ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, "upstream SSL server name: \"%s\"", name.data); - if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection, name.data) + if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection, + (char *) name.data) == 0) { ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0, -- Maxim Dounin http://nginx.org/ From nginx at rastos.org Mon Oct 3 18:43:20 2016 From: nginx at rastos.org (Rastislav Stanik) Date: Mon, 3 Oct 2016 20:43:20 +0200 Subject: [PATCH] - flastmod SSI command In-Reply-To: <57E2D7A5.2040304@rastos.org> References: <57E2D7A5.2040304@rastos.org> Message-ID: <57F2A6C8.1050504@rastos.org> On 09/21/2016 08:55 PM I've sent a patch http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008815.html that adds support for "flastmod" SSI command. I got no feedback. I'm not that familiar with local culture, so I hope I'm not too annoying by sending this again: # HG changeset patch # User Rastislav Stanik # Date 1474145684 -7200 # Sat Sep 17 22:54:44 2016 +0200 # Node ID f12b9f072e00182c8e12f24a4b8fa323c0d28080 # Parent 52367732bcbc87430e8276424356aaec3c2b6a87 add handling of flastmod SSI directive Add handling of SSI directive 'flastmod'. The directive takes a single argument 'file' and is replaced with modification time of the specified file. The filename is accepted/rejected based on the same rules as for the SSI directive 'include'. The time string is constructed based on SSI directive config timefmt. Failure to obtain the modification time is logged. diff -r 52367732bcbc -r f12b9f072e00 src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Fri Sep 16 15:13:24 2016 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Sat Sep 17 22:54:44 2016 +0200 @@ -85,6 +85,8 @@ static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); +static ngx_int_t ngx_http_ssi_flastmod(ngx_http_request_t *r, + ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data, ngx_int_t rc); static ngx_int_t ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data, @@ -223,6 +225,8 @@ #define NGX_HTTP_SSI_INCLUDE_SET 3 #define NGX_HTTP_SSI_INCLUDE_STUB 4 +#define NGX_HTTP_SSI_FLASTMOD_FILE 0 + #define NGX_HTTP_SSI_ECHO_VAR 0 #define NGX_HTTP_SSI_ECHO_DEFAULT 1 #define NGX_HTTP_SSI_ECHO_ENCODING 2 @@ -247,6 +251,10 @@ { ngx_null_string, 0, 0, 0 } }; +static ngx_http_ssi_param_t ngx_http_ssi_flastmod_params[] = { + { ngx_string("file"), NGX_HTTP_SSI_FLASTMOD_FILE, 0, 0 } +}; + static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = { { ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 }, @@ -308,7 +316,8 @@ ngx_http_ssi_block_params, 0, 0, 0 }, { ngx_string("endblock"), ngx_http_ssi_endblock, ngx_http_ssi_no_params, 0, 1, 0 }, - + { ngx_string("flastmod"), ngx_http_ssi_flastmod, + ngx_http_ssi_flastmod_params, 0, 0, 0 }, { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -2197,6 +2206,97 @@ return NGX_OK; } +static ngx_int_t +ngx_http_ssi_flastmod(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, + ngx_str_t **params) +{ + ngx_str_t *file; + ngx_str_t current_path; + ngx_uint_t flags; + ngx_int_t rc; + ngx_str_t args; + size_t root; + struct stat st_buf; + u_char *endpos; + char *statpath; + struct tm mod_time; + + file = params[NGX_HTTP_SSI_FLASTMOD_FILE]; + + if (file == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "no parameter in \"flastmod\" SSI command"); + return NGX_HTTP_SSI_ERROR; + } + + rc = ngx_http_ssi_evaluate_string(r, ctx, file, 0); + + if (rc != NGX_OK) { + return rc; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ssi flastmod: \"%V\"", file); + + ngx_str_null(&args); + flags = NGX_HTTP_LOG_UNSAFE; + + if (ngx_http_parse_unsafe_uri(r, file, &args, &flags) != NGX_OK) { + return NGX_HTTP_SSI_ERROR; + } + + root=0; + ngx_http_map_uri_to_path(r, ¤t_path, &root, 0); + // in worst case we will append the flastmod file at the end of the current pathname and add terminating zero + statpath=ngx_pcalloc(r->pool,current_path.len+file->len+1); + if (!statpath) { + return NGX_HTTP_SSI_ERROR; + } + // write the current pathname to 'statpath' + strncpy(statpath,current_path.data,current_path.len); + endpos=statpath+current_path.len; + // find the last slash + for (;endpos>current_path.data && !ngx_path_separator(*endpos);endpos--) + ; + // append the flastmod file after last slash + strncpy(endpos+1,file->data,file->len); + *(endpos+1+file->len)='\0'; // zero terminate the string so that we can pass it to stat(2) + + if (0==stat(statpath,&st_buf)) { + if (gmtime_r(&st_buf.st_mtim.tv_sec,&mod_time)) { + char *result=NULL; + ngx_uint_t len=0; + ngx_buf_t *b=NULL; + + result = ngx_pcalloc(r->pool, NGX_HTTP_SSI_MAX_FLASTMOD); + if (result) { + // convert the modification time to string: + len=strftime(result,NGX_HTTP_SSI_MAX_FLASTMOD,ctx->timefmt.data,&mod_time); + b = ngx_calloc_buf(r->pool); + if (b) { + ngx_chain_t *cl = ngx_alloc_chain_link(r->pool); + if (cl) { + // insert the time string into the http response: + b->memory = 1; + b->pos = result; + b->last = result + len; + + cl->buf = b; + cl->next = NULL; + *ctx->last_out = cl; + ctx->last_out = &cl->next; + return NGX_OK; + } + } + } + } + } + else + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "could not stat() \"%s\" file. err=%d",statpath,ngx_errno); + + return NGX_HTTP_SSI_ERROR; +} static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data, ngx_int_t rc) diff -r 52367732bcbc -r f12b9f072e00 src/http/modules/ngx_http_ssi_filter_module.h --- a/src/http/modules/ngx_http_ssi_filter_module.h Fri Sep 16 15:13:24 2016 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.h Sat Sep 17 22:54:44 2016 +0200 @@ -30,6 +30,9 @@ #define NGX_HTTP_SSI_ENTITY_ENCODING 2 +#define NGX_HTTP_SSI_MAX_FLASTMOD 100 + + typedef struct { ngx_hash_t hash; ngx_hash_keys_arrays_t commands; From ru at nginx.com Tue Oct 4 08:27:00 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 4 Oct 2016 11:27:00 +0300 Subject: Inconsistent order for ngx_destroy_pool() and ngx_close_connection() In-Reply-To: References: <20161003074553.GI8172@lo0.su> Message-ID: <20161004082700.GM8172@lo0.su> On Mon, Oct 03, 2016 at 11:36:19PM +1100, Lawrence Stewart wrote: > Hi Ruslan, > > On Mon, Oct 3, 2016 at 6:45 PM, Ruslan Ermilov wrote: > > > On Mon, Oct 03, 2016 at 03:37:38PM +1100, Lawrence Stewart wrote: > > > Hi all, > > > > > > I need to pull kernel data using getsockopt() for a connection prior to > > the > > > socket being closed. A pool cleanup handler registered with the > > > ngx_connection_t's pool would seem to be the right way to do this, but > > > ngx_http_close_connection() calls ngx_close_connection() prior to > > > ngx_destroy_pool(), which means my cleanup handler sees a closed socket. > > > > > > A look through ngx_close_connection() and the functions it calls would > > lead > > > me to believe it should be safe (and possible even desirable in an > > ordering > > > sense) to destroy the connection's pool prior to calling > > > ngx_close_connection(). > > > > If we talk about client connections, then c->log is allocated from > > c->pool, and c->read->log and c->write->log also use this log object, > > see ngx_event_accept(). > > > > A look through ngx_close_connection() shows that nearly every call > > it makes: ngx_log_error, ngx_del_timer, ngx_del_conn, ngx_del_event, > > ngx_delete_posted_event, and ngx_reusable_connection need c->log > > which would be destroyed if c->pool was destroyed. > > > > Thanks, I missed this log allocation detail. > > > > > > > There is an existence proof in the nginx tree that > > > this is reasonable to do (see [1]) and there is also a comment in > > > ngx_close_connection() that implies it expects that the connection's pool > > > has already been destroyed i.e. > > > > > > /* we use ngx_cycle->log because c->log was in c->pool */ > > > > This comment seems outdated since rev. c52408583801 which removed > > the ngx_destroy_pool(c->pool) call from ngx_close_connection(): > > > > > Ah, ok. > > > > : @@ -388,8 +387,6 @@ void ngx_close_connection(ngx_connection > > : c->fd = (ngx_socket_t) -1; > > : c->data = NULL; > > : > > : - ngx_destroy_pool(c->pool); > > : - > > : if (ngx_close_socket(fd) == -1) { > > : > > : /* we use ngx_cycle->log because c->log was in c->pool */ > > > > > Are there some subtleties I'm missing, or is it correct and reasonable to > > > always call ngx_destroy_pool() on a connection's pool prior to calling > > > ngx_close_connection()? > > > > On the contrary, the upstream connection's pool is destroyed > > before calling ngx_close_connection(), see ngx_http_upstream_next() > > and ngx_http_upstream_finalize_request(). This is safe because > > the upstream connection reuses the client connection's log, see > > ngx_http_upstream_connect(). > > > > Ah, I missed this detail too. Thanks for the pointer. > > So given that my idea is a fail, what is the recommended way to hook > connection tear down from a module so that I can achieve my goal? See if ngx_http_cleanup_add() fits your needs. From igor at sysoev.ru Tue Oct 4 08:29:24 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 04 Oct 2016 08:29:24 +0000 Subject: [njs] A dead code found by Coverity Scan has been removed. Message-ID: details: http://hg.nginx.org/njs/rev/1261cc58591e branches: changeset: 188:1261cc58591e user: Igor Sysoev date: Tue Oct 04 11:28:29 2016 +0300 description: A dead code found by Coverity Scan has been removed. diffstat: njs/njs_parser_expression.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diffs (15 lines): diff -r 8c2cea409034 -r 1261cc58591e njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Fri Sep 30 22:07:07 2016 +0300 +++ b/njs/njs_parser_expression.c Tue Oct 04 11:28:29 2016 +0300 @@ -971,11 +971,6 @@ njs_parser_call_expression(njs_vm_t *vm, func->ctor = 0; - if (token != NJS_TOKEN_OPEN_PARENTHESIS) { - parser->node = func; - return token; - } - token = njs_parser_arguments(vm, parser, func); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; From arut at nginx.com Tue Oct 4 10:48:15 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 04 Oct 2016 10:48:15 +0000 Subject: [nginx] Do not set last_buf flag in subrequests. Message-ID: details: http://hg.nginx.org/nginx/rev/6136a51f9c21 branches: changeset: 6722:6136a51f9c21 user: Roman Arutyunyan date: Mon Oct 03 20:48:51 2016 +0300 description: Do not set last_buf flag in subrequests. The last_buf flag should only be set in the last buffer of the main request. Otherwise, several last_buf flags can appear in output. This can, for example, break the chunked filter, which will include several final chunks in output. diffstat: src/http/modules/ngx_http_mp4_module.c | 2 +- src/http/modules/ngx_http_range_filter_module.c | 3 ++- src/http/ngx_http_special_response.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diffs (37 lines): diff -r 48bab8b83f4e -r 6136a51f9c21 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Mon Oct 03 15:58:30 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Mon Oct 03 20:48:51 2016 +0300 @@ -1144,7 +1144,7 @@ ngx_http_mp4_read_mdat_atom(ngx_http_mp4 data = &mp4->mdat_data_buf; data->file = &mp4->file; data->in_file = 1; - data->last_buf = 1; + data->last_buf = (mp4->request == mp4->request->main) ? 1 : 0; data->last_in_chain = 1; data->file_last = mp4->offset + atom_data_size; diff -r 48bab8b83f4e -r 6136a51f9c21 src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c Mon Oct 03 15:58:30 2016 +0300 +++ b/src/http/modules/ngx_http_range_filter_module.c Mon Oct 03 20:48:51 2016 +0300 @@ -750,7 +750,8 @@ ngx_http_range_singlepart_body(ngx_http_ buf->last -= (size_t) (last - range->end); } - buf->last_buf = 1; + buf->last_buf = (r == r->main) ? 1 : 0; + buf->last_in_chain = 1; *ll = cl; cl->next = NULL; diff -r 48bab8b83f4e -r 6136a51f9c21 src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c Mon Oct 03 15:58:30 2016 +0300 +++ b/src/http/ngx_http_special_response.c Mon Oct 03 20:48:51 2016 +0300 @@ -792,7 +792,7 @@ ngx_http_send_refresh(ngx_http_request_t b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail, sizeof(ngx_http_msie_refresh_tail) - 1); - b->last_buf = 1; + b->last_buf = (r == r->main) ? 1 : 0; b->last_in_chain = 1; out.buf = b; From arut at nginx.com Tue Oct 4 10:48:18 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 04 Oct 2016 10:48:18 +0000 Subject: [nginx] Addition filter: set last_in_chain flag when clearing last_buf. Message-ID: details: http://hg.nginx.org/nginx/rev/ebba2f980489 branches: changeset: 6723:ebba2f980489 user: Roman Arutyunyan date: Mon Oct 03 21:03:27 2016 +0300 description: Addition filter: set last_in_chain flag when clearing last_buf. When the last_buf flag is cleared for add_after_body to append more data from a subrequest, other filters may still have buffered data, which should be flushed at this point. For example, the sub_filter may have a partial match buffered, which will only be flushed after the subrequest is done, ending up with interleaved data in output. Setting last_in_chain instead of last_buf flushes the data and fixes the order of output buffers. diffstat: src/http/modules/ngx_http_addition_filter_module.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 6136a51f9c21 -r ebba2f980489 src/http/modules/ngx_http_addition_filter_module.c --- a/src/http/modules/ngx_http_addition_filter_module.c Mon Oct 03 20:48:51 2016 +0300 +++ b/src/http/modules/ngx_http_addition_filter_module.c Mon Oct 03 21:03:27 2016 +0300 @@ -171,6 +171,7 @@ ngx_http_addition_body_filter(ngx_http_r for (cl = in; cl; cl = cl->next) { if (cl->buf->last_buf) { cl->buf->last_buf = 0; + cl->buf->last_in_chain = 1; cl->buf->sync = 1; last = 1; } From mdounin at mdounin.ru Tue Oct 4 13:41:23 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 04 Oct 2016 13:41:23 +0000 Subject: [nginx] Configure: removed the --with-ipv6 option. Message-ID: details: http://hg.nginx.org/nginx/rev/a6d116645c51 branches: changeset: 6724:a6d116645c51 user: Maxim Dounin date: Tue Oct 04 16:38:14 2016 +0300 description: Configure: removed the --with-ipv6 option. IPv6 now compiled-in automatically if support is found. If there is a need to disable it for some reason, --with-cc-opt="-DNGX_HAVE_INET6=0" can be used for this. diffstat: auto/lib/geoip/conf | 20 +++++++++----------- auto/options | 8 +++++--- auto/os/win32 | 4 +--- auto/unix | 26 ++++++++++++-------------- misc/GNUmakefile | 3 +-- 5 files changed, 28 insertions(+), 33 deletions(-) diffs (124 lines): diff --git a/auto/lib/geoip/conf b/auto/lib/geoip/conf --- a/auto/lib/geoip/conf +++ b/auto/lib/geoip/conf @@ -74,17 +74,15 @@ if [ $ngx_found = yes ]; then NGX_LIB_GEOIP=$ngx_feature_libs - if [ $NGX_IPV6 = YES ]; then - ngx_feature="GeoIP IPv6 support" - ngx_feature_name="NGX_HAVE_GEOIP_V6" - ngx_feature_run=no - ngx_feature_incs="#include - #include " - #ngx_feature_path= - #ngx_feature_libs= - ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);" - . auto/feature - fi + ngx_feature="GeoIP IPv6 support" + ngx_feature_name="NGX_HAVE_GEOIP_V6" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + #ngx_feature_path= + #ngx_feature_libs= + ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);" + . auto/feature else diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -44,7 +44,6 @@ EVENT_POLL=NO USE_THREADS=NO NGX_FILE_AIO=NO -NGX_IPV6=NO HTTP=YES @@ -204,7 +203,11 @@ do --with-threads) USE_THREADS=YES ;; --with-file-aio) NGX_FILE_AIO=YES ;; - --with-ipv6) NGX_IPV6=YES ;; + + --with-ipv6) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-ipv6\" option is deprecated" + ;; --without-http) HTTP=NO ;; --without-http-cache) HTTP_CACHE=NO ;; @@ -424,7 +427,6 @@ cat << END --with-threads enable thread pool support --with-file-aio enable file AIO support - --with-ipv6 enable IPv6 support --with-http_ssl_module enable ngx_http_ssl_module --with-http_v2_module enable ngx_http_v2_module diff --git a/auto/os/win32 b/auto/os/win32 --- a/auto/os/win32 +++ b/auto/os/win32 @@ -37,8 +37,6 @@ if [ $EVENT_SELECT = NO ]; then EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE" fi -if [ $NGX_IPV6 = YES ]; then - have=NGX_HAVE_INET6 . auto/have -fi +have=NGX_HAVE_INET6 . auto/have have=NGX_HAVE_IOCP . auto/have diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -637,20 +637,18 @@ ngx_param=NGX_MAX_TIME_T_VALUE; ngx_valu # syscalls, libc calls and some features -if [ $NGX_IPV6 = YES ]; then - ngx_feature="AF_INET6" - ngx_feature_name="NGX_HAVE_INET6" - ngx_feature_run=no - ngx_feature_incs="#include - #include - #include " - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="struct sockaddr_in6 sin6; - sin6.sin6_family = AF_INET6; - (void) sin6" - . auto/feature -fi +ngx_feature="AF_INET6" +ngx_feature_name="NGX_HAVE_INET6" +ngx_feature_run=no +ngx_feature_incs="#include + #include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="struct sockaddr_in6 sin6; + sin6.sin6_family = AF_INET6; + (void) sin6" +. auto/feature ngx_feature="setproctitle()" diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -84,8 +84,7 @@ win32: --with-openssl-opt=no-asm \ --with-http_ssl_module \ --with-mail_ssl_module \ - --with-stream_ssl_module \ - --with-ipv6 + --with-stream_ssl_module zip: export From mdounin at mdounin.ru Tue Oct 4 14:28:40 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 04 Oct 2016 14:28:40 +0000 Subject: [nginx] SSL: use X509_check_host() with LibreSSL. Message-ID: details: http://hg.nginx.org/nginx/rev/9b9ae81cd4f0 branches: changeset: 6725:9b9ae81cd4f0 user: Maxim Dounin date: Tue Oct 04 17:26:45 2016 +0300 description: SSL: use X509_check_host() with LibreSSL. Explicit checks for OPENSSL_VERSION_NUMBER replaced with checks for X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, thus allowing X509_check_host() to be used with other libraries. In particular, X509_check_host() was introduced in LibreSSL 2.5.0. diffstat: src/event/ngx_event_openssl.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (30 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -55,7 +55,7 @@ static int ngx_ssl_session_ticket_key_ca HMAC_CTX *hctx, int enc); #endif -#if OPENSSL_VERSION_NUMBER < 0x10002002L +#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str); #endif @@ -3092,7 +3092,7 @@ ngx_ssl_check_host(ngx_connection_t *c, return NGX_ERROR; } -#if OPENSSL_VERSION_NUMBER >= 0x10002002L +#ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT /* X509_check_host() is only available in OpenSSL 1.0.2+ */ @@ -3209,7 +3209,7 @@ found: } -#if OPENSSL_VERSION_NUMBER < 0x10002002L +#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern) From akshayaamohan05 at gmail.com Tue Oct 4 16:34:16 2016 From: akshayaamohan05 at gmail.com (AKSHAYAA MOHAN) Date: Tue, 4 Oct 2016 22:04:16 +0530 Subject: Default server block for HTTP requests Message-ID: Hi, We have configured default server block as follows. server { listen 7777 default_server; server_name _; access_log /usr/share/nginx/access_logs/7777; error_log /usr/share/nginx/error_logs/7777 warn; server_tokens off; underscores_in_headers on; return 444; } When trying to access the HTTP endpoint with this port, the default server block is always getting picked up although there is an exact match server block. This does not happen for SSL requests. The default server block configured for non ssl and ssl differ only w.r.t ssl directives. Not sure what we are missing here. Please help. Regards -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue Oct 4 16:37:34 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 4 Oct 2016 19:37:34 +0300 Subject: Default server block for HTTP requests In-Reply-To: References: Message-ID: <20161004163734.GO73038@mdounin.ru> Hello! On Tue, Oct 04, 2016 at 10:04:16PM +0530, AKSHAYAA MOHAN wrote: > We have configured default server block as follows. [...] This doesn't look relevant to nginx-devel@ list. Please use nginx@ for usage questions. Thank you. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue Oct 4 21:25:13 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 5 Oct 2016 00:25:13 +0300 Subject: [PATCH] Core: fixed uninitialized memory access In-Reply-To: <20160929220911.GU19300@manetheren.hodor.cz> References: <20160927212259.GT19300@manetheren.hodor.cz> <20160929060215.GV73038@mdounin.ru> <20160929220911.GU19300@manetheren.hodor.cz> Message-ID: <20161004212513.GS73038@mdounin.ru> Hello! On Fri, Sep 30, 2016 at 12:09:12AM +0200, Jan Seda wrote: > Hello. > > On 2016-09-29, 09:02:16, Maxim Dounin wrote: > > Thanks for catching this. > > > > Dropping the length returned by getsockname() doesn't look like > > a correct solution though. Instead, teaching ngx_cmp_sockaddr() to > > compare sockaddrs with not-completely-filled sun_path - that is, > > respecting socklen - should be the right way to go. > > > > Please try the following patch: > > Seems to work OK. Cannot reproduce the problem anymore. Thanks. > > BTW, wouldn't s/ngx_palloc/ngx_pcalloc/ in ngx_set_inherited_sockets() > be prudent anyway? It shouldn't be needed unless there is a bug elsewhere. > Also, I see your patch is prepared for abstract namespace sockets. Is > this feature planned soon? I cobbled up a patch for that (attached) and > such sockets now interop with haproxy (abns@ scheme) and socat (with > unix-tightsocklen=0). But it probably is not production-ready. No, there are no plans, I've just tried to keep the code more or less generic. Just in case you are interested, below is slightly cleaned up version of your patch. # HG changeset patch # User Maxim Dounin # Date 1475091257 -7200 # Wed Sep 28 21:34:17 2016 +0200 # Node ID cd448f5f1eec8d11bd9d942d44aa117de397c9d1 # Parent 9b9ae81cd4f01ed60e7bab323d49b470cec69d9e Core: support for abstract namespace sockets on Linux. Abstract sockets recognized in the "unix:@name" form. Rest of the struct sockaddr_un's sun_path is filled with zeros, and socklen is set to be sizeof(struct sockaddr_un). This is expected to be compatible with HAProxy (abns@ scheme) and socat (with unix-tightsocklen=0). Based on a patch by Jan Seda, http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008851.html. diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -562,7 +562,9 @@ ngx_open_listening_sockets(ngx_cycle_t * #if (NGX_HAVE_UNIX_DOMAIN) - if (ls[i].sockaddr->sa_family == AF_UNIX) { + if (ls[i].sockaddr->sa_family == AF_UNIX + && ls[i].addr_text.data[sizeof("unix:") - 1] != '@') + { mode_t mode; u_char *name; @@ -1006,6 +1008,7 @@ ngx_close_listening_sockets(ngx_cycle_t #if (NGX_HAVE_UNIX_DOMAIN) if (ls[i].sockaddr->sa_family == AF_UNIX + && ls[i].addr_text.data[sizeof("unix:") - 1] != '@' && ngx_process <= NGX_PROCESS_MASTER && ngx_new_binary == 0) { diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -698,7 +698,9 @@ old_shm_zone_done: #if (NGX_HAVE_UNIX_DOMAIN) - if (ls[i].sockaddr->sa_family == AF_UNIX) { + if (ls[i].sockaddr->sa_family == AF_UNIX + && ls[i].addr_text.data[sizeof("unix:") - 1] != '@') + { u_char *name; name = ls[i].addr_text.data + sizeof("unix:") - 1; diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -240,6 +240,9 @@ ngx_sock_ntop(struct sockaddr *sa, sockl if (socklen <= (socklen_t) offsetof(struct sockaddr_un, sun_path)) { p = ngx_snprintf(text, len, "unix:%Z"); + } else if (saun->sun_path[0] == '\0') { + p = ngx_snprintf(text, len, "unix:@%s%Z", &saun->sun_path[1]); + } else { p = ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path); } @@ -740,6 +743,10 @@ ngx_parse_unix_domain_url(ngx_pool_t *po saun->sun_family = AF_UNIX; (void) ngx_cpystrn((u_char *) saun->sun_path, path, len); + if (path[0] == '@') { + saun->sun_path[0] = '\0'; + } + u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t)); if (u->addrs == NULL) { return NGX_ERROR; @@ -756,6 +763,10 @@ ngx_parse_unix_domain_url(ngx_pool_t *po saun->sun_family = AF_UNIX; (void) ngx_cpystrn((u_char *) saun->sun_path, path, len); + if (path[0] == '@') { + saun->sun_path[0] = '\0'; + } + u->addrs[0].sockaddr = (struct sockaddr *) saun; u->addrs[0].socklen = sizeof(struct sockaddr_un); u->addrs[0].name.len = len + 4; -- Maxim Dounin http://nginx.org/ From ru at nginx.com Wed Oct 5 10:58:18 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 05 Oct 2016 10:58:18 +0000 Subject: [nginx] Core: use c->log while closing connection. Message-ID: details: http://hg.nginx.org/nginx/rev/631753428ecb branches: changeset: 6726:631753428ecb user: Ruslan Ermilov date: Wed Oct 05 13:57:43 2016 +0300 description: Core: use c->log while closing connection. c->pool is not destroyed here since c52408583801. diffstat: src/core/ngx_connection.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diffs (15 lines): diff -r 9b9ae81cd4f0 -r 631753428ecb src/core/ngx_connection.c --- a/src/core/ngx_connection.c Tue Oct 04 17:26:45 2016 +0300 +++ b/src/core/ngx_connection.c Wed Oct 05 13:57:43 2016 +0300 @@ -1191,10 +1191,7 @@ ngx_close_connection(ngx_connection_t *c level = NGX_LOG_CRIT; } - /* we use ngx_cycle->log because c->log was in c->pool */ - - ngx_log_error(level, ngx_cycle->log, err, - ngx_close_socket_n " %d failed", fd); + ngx_log_error(level, c->log, err, ngx_close_socket_n " %d failed", fd); } } From xeioex at nginx.com Wed Oct 5 12:45:20 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 05 Oct 2016 12:45:20 +0000 Subject: [nginx] Cache: cache manager limits. Message-ID: details: http://hg.nginx.org/nginx/rev/ca709bca4b77 branches: changeset: 6727:ca709bca4b77 user: Dmitry Volyntsev date: Wed Oct 05 14:22:30 2016 +0300 description: Cache: cache manager limits. The new parameters "manager_files", "manager_sleep" and "manager_threshold" were added to proxy_cache_path and friends. Note that ngx_path_manager_pt was changed to return ngx_msec_t instead of time_t (API change). diffstat: src/core/ngx_file.h | 2 +- src/http/ngx_http_cache.h | 4 + src/http/ngx_http_file_cache.c | 103 +++++++++++++++++++++++++++++++++++--- src/os/unix/ngx_process_cycle.c | 6 +- src/os/win32/ngx_process_cycle.c | 6 +- 5 files changed, 105 insertions(+), 16 deletions(-) diffs (270 lines): diff -r 631753428ecb -r ca709bca4b77 src/core/ngx_file.h --- a/src/core/ngx_file.h Wed Oct 05 13:57:43 2016 +0300 +++ b/src/core/ngx_file.h Wed Oct 05 14:22:30 2016 +0300 @@ -42,7 +42,7 @@ struct ngx_file_s { #define NGX_MAX_PATH_LEVEL 3 -typedef time_t (*ngx_path_manager_pt) (void *data); +typedef ngx_msec_t (*ngx_path_manager_pt) (void *data); typedef ngx_msec_t (*ngx_path_purger_pt) (void *data); typedef void (*ngx_path_loader_pt) (void *data); diff -r 631753428ecb -r ca709bca4b77 src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h Wed Oct 05 13:57:43 2016 +0300 +++ b/src/http/ngx_http_cache.h Wed Oct 05 14:22:30 2016 +0300 @@ -166,6 +166,10 @@ struct ngx_http_file_cache_s { ngx_msec_t loader_sleep; ngx_msec_t loader_threshold; + ngx_uint_t manager_files; + ngx_msec_t manager_sleep; + ngx_msec_t manager_threshold; + ngx_shm_zone_t *shm_zone; }; diff -r 631753428ecb -r ca709bca4b77 src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Wed Oct 05 13:57:43 2016 +0300 +++ b/src/http/ngx_http_file_cache.c Wed Oct 05 14:22:30 2016 +0300 @@ -1759,6 +1759,7 @@ ngx_http_file_cache_expire(ngx_http_file size_t len; time_t now, wait; ngx_path_t *path; + ngx_msec_t elapsed; ngx_queue_t *q; ngx_http_file_cache_node_t *fcn; u_char key[2 * NGX_HTTP_CACHE_KEY_LEN]; @@ -1810,7 +1811,7 @@ ngx_http_file_cache_expire(ngx_http_file if (fcn->count == 0) { ngx_http_file_cache_delete(cache, q, name); - continue; + goto next; } if (fcn->deleting) { @@ -1836,6 +1837,22 @@ ngx_http_file_cache_expire(ngx_http_file ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "ignore long locked inactive cache entry %*s, count:%d", (size_t) 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); + +next: + + if (++cache->files >= cache->manager_files) { + wait = 0; + break; + } + + ngx_time_update(); + + elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last)); + + if (elapsed >= cache->manager_threshold) { + wait = 0; + break; + } } ngx_shmtx_unlock(&cache->shpool->mutex); @@ -1897,20 +1914,25 @@ ngx_http_file_cache_delete(ngx_http_file } -static time_t +static ngx_msec_t ngx_http_file_cache_manager(void *data) { ngx_http_file_cache_t *cache = data; off_t size; time_t next, wait; + ngx_msec_t elapsed; ngx_uint_t count, watermark; - next = ngx_http_file_cache_expire(cache); - cache->last = ngx_current_msec; cache->files = 0; + next = ngx_http_file_cache_expire(cache); + + if (next == 0) { + return cache->manager_sleep; + } + for ( ;; ) { ngx_shmtx_lock(&cache->shpool->mutex); @@ -1925,17 +1947,29 @@ ngx_http_file_cache_manager(void *data) size, count, (ngx_int_t) watermark); if (size < cache->max_size && count < watermark) { - return next; + return (ngx_msec_t) next * 1000; } wait = ngx_http_file_cache_forced_expire(cache); if (wait > 0) { - return wait; + return (ngx_msec_t) wait * 1000; } if (ngx_quit || ngx_terminate) { - return next; + return (ngx_msec_t) next * 1000; + } + + if (++cache->files >= cache->manager_files) { + return cache->manager_sleep; + } + + ngx_time_update(); + + elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last)); + + if (elapsed >= cache->manager_threshold) { + return cache->manager_sleep; } } } @@ -2211,8 +2245,9 @@ ngx_http_file_cache_set_slot(ngx_conf_t size_t len; ssize_t size; ngx_str_t s, name, *value; - ngx_int_t loader_files; - ngx_msec_t loader_sleep, loader_threshold; + ngx_int_t loader_files, manager_files; + ngx_msec_t loader_sleep, manager_sleep, loader_threshold, + manager_threshold; ngx_uint_t i, n, use_temp_path; ngx_array_t *caches; ngx_http_file_cache_t *cache, **ce; @@ -2230,10 +2265,15 @@ ngx_http_file_cache_set_slot(ngx_conf_t use_temp_path = 1; inactive = 600; + loader_files = 100; loader_sleep = 50; loader_threshold = 200; + manager_files = 100; + manager_sleep = 50; + manager_threshold = 200; + name.len = 0; size = 0; max_size = NGX_MAX_OFF_T_VALUE; @@ -2405,6 +2445,48 @@ ngx_http_file_cache_set_slot(ngx_conf_t continue; } + if (ngx_strncmp(value[i].data, "manager_files=", 14) == 0) { + + manager_files = ngx_atoi(value[i].data + 14, value[i].len - 14); + if (manager_files == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid manager_files value \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + + if (ngx_strncmp(value[i].data, "manager_sleep=", 14) == 0) { + + s.len = value[i].len - 14; + s.data = value[i].data + 14; + + manager_sleep = ngx_parse_time(&s, 0); + if (manager_sleep == (ngx_msec_t) NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid manager_sleep value \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + + if (ngx_strncmp(value[i].data, "manager_threshold=", 18) == 0) { + + s.len = value[i].len - 18; + s.data = value[i].data + 18; + + manager_threshold = ngx_parse_time(&s, 0); + if (manager_threshold == (ngx_msec_t) NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid manager_threshold value \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; @@ -2425,6 +2507,9 @@ ngx_http_file_cache_set_slot(ngx_conf_t cache->loader_files = loader_files; cache->loader_sleep = loader_sleep; cache->loader_threshold = loader_threshold; + cache->manager_files = manager_files; + cache->manager_sleep = manager_sleep; + cache->manager_threshold = manager_threshold; if (ngx_add_path(cf, &cache->path) != NGX_OK) { return NGX_CONF_ERROR; diff -r 631753428ecb -r ca709bca4b77 src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c Wed Oct 05 13:57:43 2016 +0300 +++ b/src/os/unix/ngx_process_cycle.c Wed Oct 05 14:22:30 2016 +0300 @@ -1148,11 +1148,11 @@ ngx_cache_manager_process_cycle(ngx_cycl static void ngx_cache_manager_process_handler(ngx_event_t *ev) { - time_t next, n; ngx_uint_t i; + ngx_msec_t next, n; ngx_path_t **path; - next = 60 * 60; + next = 60 * 60 * 1000; path = ngx_cycle->paths.elts; for (i = 0; i < ngx_cycle->paths.nelts; i++) { @@ -1170,7 +1170,7 @@ ngx_cache_manager_process_handler(ngx_ev next = 1; } - ngx_add_timer(ev, next * 1000); + ngx_add_timer(ev, next); } diff -r 631753428ecb -r ca709bca4b77 src/os/win32/ngx_process_cycle.c --- a/src/os/win32/ngx_process_cycle.c Wed Oct 05 13:57:43 2016 +0300 +++ b/src/os/win32/ngx_process_cycle.c Wed Oct 05 14:22:30 2016 +0300 @@ -921,11 +921,11 @@ static void ngx_cache_manager_process_handler(void) { u_long ev; - time_t next, n; ngx_uint_t i; + ngx_msec_t next, n; ngx_path_t **path; - next = 60 * 60; + next = 60 * 60 * 1000; path = ngx_cycle->paths.elts; for (i = 0; i < ngx_cycle->paths.nelts; i++) { @@ -943,7 +943,7 @@ ngx_cache_manager_process_handler(void) next = 1; } - ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next * 1000); + ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next); if (ev != WAIT_TIMEOUT) { From pluknet at nginx.com Wed Oct 5 15:12:45 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Wed, 05 Oct 2016 15:12:45 +0000 Subject: [nginx] Stream ssl_preread: fixed $ssl_preread_server_name variable. Message-ID: details: http://hg.nginx.org/nginx/rev/8f75d9883730 branches: changeset: 6728:8f75d9883730 user: Sergey Kandaurov date: Wed Oct 05 18:11:39 2016 +0300 description: Stream ssl_preread: fixed $ssl_preread_server_name variable. Made sure to set the variable length only after successful SNI parsing. diffstat: src/stream/ngx_stream_ssl_preread_module.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (17 lines): diff -r ca709bca4b77 -r 8f75d9883730 src/stream/ngx_stream_ssl_preread_module.c --- a/src/stream/ngx_stream_ssl_preread_module.c Wed Oct 05 14:22:30 2016 +0300 +++ b/src/stream/ngx_stream_ssl_preread_module.c Wed Oct 05 18:11:39 2016 +0300 @@ -333,11 +333,12 @@ ngx_stream_ssl_preread_parse_record(ngx_ return NGX_ERROR; } - ctx->host.len = size; dst = ctx->host.data; break; case sw_sni_host: + ctx->host.len = (p[1] << 8) + p[2]; + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ctx->log, 0, "ssl preread: SNI hostname \"%V\"", &ctx->host); return NGX_OK; From amdeich at gmail.com Thu Oct 6 09:40:21 2016 From: amdeich at gmail.com (Andrey Kulikov) Date: Thu, 6 Oct 2016 12:40:21 +0300 Subject: [Q] How to iterate over configured locations on process init in custom module? Message-ID: Hello, I wrote a custom nginx module, which require specific initialization in worker process (it can't be done in master process). Initialization should be performed if server OR location meet certain criteria. With servers I came out to following solution: static ngx_int_t ngx_http_mega_init_process(ngx_cycle_t *cycle) { ngx_uint_t s; ngx_http_core_srv_conf_t **cscfp; ngx_http_core_main_conf_t *cmcf; ngx_http_mega_srv_conf_t *sscf; /* My module configuration */ cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); cscfp = cmcf->servers.elts; for (s = 0; s < cmcf->servers.nelts; s++) { sscf = cscfp[s]->ctx->srv_conf[ngx_http_mega_module.ctx_index]; if (!sscf || !sscf->enable) { continue; } } } But how to iterate over locations in the server? Is there are any other module, what have similar logic? Or any other place, where I can find inspiration? I've tried following, but with no luck: ngx_http_core_srv_conf_t **cscfp; ngx_http_core_loc_conf_t **clcfp; ngx_http_core_srv_conf_t *cscf; cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); cscfp = cmcf->servers.elts; for (s = 0; s < cmcf->servers.nelts; s++) { cscf = cscfp[s]; - OR - cscf = cscfp[s]->ctx->srv_conf[ngx_http_core_module.ctx_index]; if (cscf->named_locations) { for (clcfp = cscf->named_locations; *clcfp; clcfp++) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "MEGA test location: \"%V\"", &(*clcfp)->name); } } here cscf->named_locations is always NULL in both cases, despite I have a lot of locations in my servers configured in nginx.conf. -- Best wishes, Andrey Kulikov -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Oct 6 20:17:36 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 06 Oct 2016 20:17:36 +0000 Subject: [nginx] Realip: fixed duplicate processing on redirects (ticket #1098). Message-ID: details: http://hg.nginx.org/nginx/rev/cecf415643d7 branches: changeset: 6729:cecf415643d7 user: Maxim Dounin date: Thu Oct 06 23:16:05 2016 +0300 description: Realip: fixed duplicate processing on redirects (ticket #1098). Duplicate processing was possible if the address set by realip was listed in set_realip_from, and there was an internal redirect so module context was cleared. This resulted in exactly the same address being set, so this wasn't a problem before the $realip_remote_addr variable was introduced, though now results in incorrect $realip_remote_addr being picked. Fix is to use ngx_http_realip_get_module_ctx() to look up module context even if it was cleared. Additionally, the order of checks was switched to check the configuration first as it looks more effective. diffstat: src/http/modules/ngx_http_realip_module.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (23 lines): diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c --- a/src/http/modules/ngx_http_realip_module.c +++ b/src/http/modules/ngx_http_realip_module.c @@ -141,15 +141,15 @@ ngx_http_realip_handler(ngx_http_request ngx_http_realip_ctx_t *ctx; ngx_http_realip_loc_conf_t *rlcf; - ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); + rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); - if (ctx) { + if (rlcf->from == NULL) { return NGX_DECLINED; } - rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); + ctx = ngx_http_realip_get_module_ctx(r); - if (rlcf->from == NULL) { + if (ctx) { return NGX_DECLINED; } From mdounin at mdounin.ru Fri Oct 7 16:19:05 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 07 Oct 2016 16:19:05 +0000 Subject: [nginx] Core: ngx_conf_set_access_slot() user access (ticket #1096). Message-ID: details: http://hg.nginx.org/nginx/rev/1606a817c1d4 branches: changeset: 6730:1606a817c1d4 user: Maxim Dounin date: Fri Oct 07 16:59:14 2016 +0300 description: Core: ngx_conf_set_access_slot() user access (ticket #1096). Previously, user access bits were always set to "rw" unconditionally, even with "user:r" explicitly specified. With this change we only add default user access bits (0600) if they weren't set explicitly. diffstat: src/core/ngx_file.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (39 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 @@ -441,7 +441,7 @@ ngx_conf_set_access_slot(ngx_conf_t *cf, u_char *p; ngx_str_t *value; - ngx_uint_t i, right, shift, *access; + ngx_uint_t i, right, shift, *access, user; access = (ngx_uint_t *) (confp + cmd->offset); @@ -451,7 +451,8 @@ ngx_conf_set_access_slot(ngx_conf_t *cf, value = cf->args->elts; - *access = 0600; + *access = 0; + user = 0600; for (i = 1; i < cf->args->nelts; i++) { @@ -460,6 +461,7 @@ ngx_conf_set_access_slot(ngx_conf_t *cf, if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) { shift = 6; p += sizeof("user:") - 1; + user = 0; } else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) { shift = 3; @@ -486,6 +488,8 @@ ngx_conf_set_access_slot(ngx_conf_t *cf, *access |= right << shift; } + *access |= user; + return NGX_CONF_OK; invalid: From naveeniiit54 at gmail.com Fri Oct 7 17:52:16 2016 From: naveeniiit54 at gmail.com (Naveen Shukla) Date: Fri, 7 Oct 2016 10:52:16 -0700 Subject: Regarding invalid characters in headers name and value Message-ID: Where do nginx checks about invalid character in header name and value ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Fri Oct 7 18:57:45 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 7 Oct 2016 21:57:45 +0300 Subject: Regarding invalid characters in headers name and value In-Reply-To: References: Message-ID: <20161007185745.GE6646@lo0.su> On Fri, Oct 07, 2016 at 10:52:16AM -0700, Naveen Shukla wrote: > Where do nginx checks about invalid character in header name and value ? grep -r 'invalid_header = 1' src/http From rpaprocki at fearnothingproductions.net Sat Oct 8 00:51:49 2016 From: rpaprocki at fearnothingproductions.net (Robert Paprocki) Date: Fri, 7 Oct 2016 17:51:49 -0700 Subject: Limit req: Remove unused struct element Message-ID: # HG changeset patch # User Robert Paprocki # Date 1475887216 25200 # Fri Oct 07 17:40:16 2016 -0700 # Node ID eb5109e432b6138d2a128fd3766be2dbb11974af # Parent 1606a817c1d48ed351f1dd7d9cb9c996e2c77b9a Limit req: Remove unused struct element dummy doesn't appear to be necessary for padding alignment, and is unused in this module. diff -r 1606a817c1d4 -r eb5109e432b6 src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/http/modules/ngx_http_limit_req_module.c Fri Oct 07 17:40:16 2016 -0700 @@ -12,7 +12,6 @@ typedef struct { u_char color; - u_char dummy; u_short len; ngx_queue_t queue; ngx_msec_t last; -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Sat Oct 8 02:15:36 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 8 Oct 2016 05:15:36 +0300 Subject: Limit req: Remove unused struct element In-Reply-To: References: Message-ID: <20161008021536.GL73038@mdounin.ru> Hello! On Fri, Oct 07, 2016 at 05:51:49PM -0700, Robert Paprocki wrote: > # HG changeset patch > # User Robert Paprocki > # Date 1475887216 25200 > # Fri Oct 07 17:40:16 2016 -0700 > # Node ID eb5109e432b6138d2a128fd3766be2dbb11974af > # Parent 1606a817c1d48ed351f1dd7d9cb9c996e2c77b9a > Limit req: Remove unused struct element > > dummy doesn't appear to be necessary for padding alignment, > and is unused in this module. > > diff -r 1606a817c1d4 -r eb5109e432b6 > src/http/modules/ngx_http_limit_req_module.c > --- a/src/http/modules/ngx_http_limit_req_module.c Fri Oct 07 16:59:14 2016 > +0300 > +++ b/src/http/modules/ngx_http_limit_req_module.c Fri Oct 07 17:40:16 2016 > -0700 > @@ -12,7 +12,6 @@ > > typedef struct { > u_char color; > - u_char dummy; > u_short len; > ngx_queue_t queue; > ngx_msec_t last; While it is not stricly necessary, it corresponds to the "data" field in the ngx_rbtree_node_t and it is better to have it explicitly present to simplify understanding of the code. -- Maxim Dounin http://nginx.org/ From robn at fastmail.com Sat Oct 8 07:31:02 2016 From: robn at fastmail.com (=?utf-8?b?Um9iIE4g4piF?=) Date: Sat, 08 Oct 2016 18:31:02 +1100 Subject: [PATCH] Mail: Support SASL EXTERNAL (RFC 4422) Message-ID: <205f2148260460379f9b.1475911862@lena> # HG changeset patch # User Rob N ? # Date 1475910300 -39600 # Sat Oct 08 18:05:00 2016 +1100 # Node ID 205f2148260460379f9b0889cdb8015994028c73 # Parent 1606a817c1d48ed351f1dd7d9cb9c996e2c77b9a Mail: Support SASL EXTERNAL (RFC 4422) This is needed to allow TLS client certificate auth to work. With ssl_verify_client configured, the auth daemon can choose to allow the connection to proceed based on the certificate data. This has been tested with Thunderbird for IMAP only. I've not yet found a client that will do client certificate auth for POP3 or SMTP, and the method is not really documented anywhere that I can find. That said, its simple enough that the way I've done is probably right. diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail.h Sat Oct 08 18:05:00 2016 +1100 @@ -136,7 +136,8 @@ ngx_pop3_auth_login_username, ngx_pop3_auth_login_password, ngx_pop3_auth_plain, - ngx_pop3_auth_cram_md5 + ngx_pop3_auth_cram_md5, + ngx_pop3_auth_external } ngx_pop3_state_e; @@ -146,6 +147,7 @@ ngx_imap_auth_login_password, ngx_imap_auth_plain, ngx_imap_auth_cram_md5, + ngx_imap_auth_external, ngx_imap_login, ngx_imap_user, ngx_imap_passwd @@ -158,6 +160,7 @@ ngx_smtp_auth_login_password, ngx_smtp_auth_plain, ngx_smtp_auth_cram_md5, + ngx_smtp_auth_external, ngx_smtp_helo, ngx_smtp_helo_xclient, ngx_smtp_helo_from, @@ -289,14 +292,16 @@ #define NGX_MAIL_AUTH_LOGIN_USERNAME 2 #define NGX_MAIL_AUTH_APOP 3 #define NGX_MAIL_AUTH_CRAM_MD5 4 -#define NGX_MAIL_AUTH_NONE 5 +#define NGX_MAIL_AUTH_EXTERNAL 5 +#define NGX_MAIL_AUTH_NONE 6 #define NGX_MAIL_AUTH_PLAIN_ENABLED 0x0002 #define NGX_MAIL_AUTH_LOGIN_ENABLED 0x0004 #define NGX_MAIL_AUTH_APOP_ENABLED 0x0008 #define NGX_MAIL_AUTH_CRAM_MD5_ENABLED 0x0010 -#define NGX_MAIL_AUTH_NONE_ENABLED 0x0020 +#define NGX_MAIL_AUTH_EXTERNAL_ENABLED 0x0020 +#define NGX_MAIL_AUTH_NONE_ENABLED 0x0040 #define NGX_MAIL_PARSE_INVALID_COMMAND 20 @@ -381,6 +386,8 @@ ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c, char *prefix, size_t len); ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c); +ngx_int_t ngx_mail_auth_external(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n); ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c); void ngx_mail_send(ngx_event_t *wev); diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_auth_http_module.c Sat Oct 08 18:05:00 2016 +1100 @@ -151,6 +151,7 @@ ngx_string("plain"), ngx_string("apop"), ngx_string("cram-md5"), + ngx_string("external"), ngx_string("none") }; diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_handler.c Sat Oct 08 18:05:00 2016 +1100 @@ -612,6 +612,40 @@ } +ngx_int_t +ngx_mail_auth_external(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n) +{ + ngx_str_t *arg, external; + + arg = s->args.elts; + + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, + "mail auth external: \"%V\"", &arg[n]); + + external.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len)); + if (external.data == NULL) { + return NGX_ERROR; + } + + if (ngx_decode_base64(&external, &arg[n]) != NGX_OK) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent invalid base64 encoding in AUTH EXTERNAL command"); + return NGX_MAIL_PARSE_INVALID_COMMAND; + } + + s->login.len = external.len; + s->login.data = external.data; + + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, + "mail auth external: \"%V\"", &s->login); + + s->auth_method = NGX_MAIL_AUTH_EXTERNAL; + + return NGX_DONE; +} + + void ngx_mail_send(ngx_event_t *wev) { diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_imap_handler.c --- a/src/mail/ngx_mail_imap_handler.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_imap_handler.c Sat Oct 08 18:05:00 2016 +1100 @@ -222,6 +222,10 @@ case ngx_imap_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_imap_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } else if (rc == NGX_IMAP_NEXT) { @@ -399,6 +403,13 @@ } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, imap_username); + s->mail_state = ngx_imap_auth_external; + + return NGX_OK; } return rc; diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_imap_module.c --- a/src/mail/ngx_mail_imap_module.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_imap_module.c Sat Oct 08 18:05:00 2016 +1100 @@ -29,6 +29,7 @@ { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_null_string, 0 } }; @@ -38,6 +39,7 @@ ngx_string("AUTH=LOGIN"), ngx_null_string, /* APOP */ ngx_string("AUTH=CRAM-MD5"), + ngx_string("AUTH=EXTERNAL"), ngx_null_string /* NONE */ }; @@ -179,7 +181,7 @@ } for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -205,7 +207,7 @@ auth = p; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_parse.c --- a/src/mail/ngx_mail_parse.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_parse.c Sat Oct 08 18:05:00 2016 +1100 @@ -905,13 +905,27 @@ if (arg[0].len == 8) { - if (s->args.nelts != 1) { - return NGX_MAIL_PARSE_INVALID_COMMAND; + if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) { + + if (s->args.nelts != 1) { + return NGX_MAIL_PARSE_INVALID_COMMAND; + } + + return NGX_MAIL_AUTH_CRAM_MD5; } - if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) { - return NGX_MAIL_AUTH_CRAM_MD5; + if (ngx_strncasecmp(arg[0].data, (u_char *) "EXTERNAL", 8) == 0) { + + if (s->args.nelts == 1) { + return NGX_MAIL_AUTH_EXTERNAL; + } + + if (s->args.nelts == 2) { + return ngx_mail_auth_external(s, c, 1); + } } + + return NGX_MAIL_PARSE_INVALID_COMMAND; } return NGX_MAIL_PARSE_INVALID_COMMAND; diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_pop3_handler.c Sat Oct 08 18:05:00 2016 +1100 @@ -240,6 +240,10 @@ case ngx_pop3_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_pop3_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } @@ -494,6 +498,13 @@ } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, pop3_username); + s->mail_state = ngx_pop3_auth_external; + + return NGX_OK; } return rc; diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_pop3_module.c --- a/src/mail/ngx_mail_pop3_module.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_pop3_module.c Sat Oct 08 18:05:00 2016 +1100 @@ -29,23 +29,33 @@ { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_null_string, 0 } }; -static ngx_str_t ngx_mail_pop3_auth_plain_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "." CRLF); +static ngx_str_t ngx_mail_pop3_auth_methods_capabilities[] = { + ngx_string("LOGIN PLAIN"), + ngx_null_string, /* LOGIN */ + ngx_null_string, /* APOP */ + ngx_string("CRAM-MD5"), + ngx_string("EXTERNAL"), + ngx_null_string /* NONE */ +}; -static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "CRAM-MD5" CRLF - "." CRLF); +static ngx_str_t ngx_mail_pop3_auth_methods_authnames[] = { + ngx_string("LOGIN" CRLF "PLAIN" CRLF), + ngx_null_string, /* LOGIN */ + ngx_null_string, /* APOP */ + ngx_string("CRAM-MD5" CRLF), + ngx_string("EXTERNAL" CRLF), + ngx_null_string /* NONE */ +}; + + +static ngx_str_t ngx_mail_pop3_auth_capability = + ngx_string("+OK methods supported:" CRLF); static ngx_mail_protocol_t ngx_mail_pop3_protocol = { @@ -140,7 +150,7 @@ u_char *p; size_t size, stls_only_size; ngx_str_t *c, *d; - ngx_uint_t i; + ngx_uint_t i, m; ngx_conf_merge_bitmask_value(conf->auth_methods, prev->auth_methods, @@ -179,11 +189,15 @@ stls_only_size += c[i].len + sizeof(CRLF) - 1; } - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; + size += sizeof("SASL") + 1; - } else { - size += sizeof("SASL LOGIN PLAIN" CRLF) - 1; + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + size += 1 + ngx_mail_pop3_auth_methods_capabilities[i].len; + } } p = ngx_pnalloc(cf->pool, size); @@ -202,15 +216,22 @@ *p++ = CR; *p++ = LF; } - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF, - sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1); + p = ngx_cpymem(p, "SASL", sizeof("SASL") - 1); - } else { - p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF, - sizeof("SASL LOGIN PLAIN" CRLF) - 1); + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + *p++ = ' '; + p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_capabilities[i].data, + ngx_mail_pop3_auth_methods_capabilities[i].len); + } } + *p++ = CR; *p++ = LF; + + *p++ = '.'; *p++ = CR; *p = LF; @@ -231,13 +252,39 @@ *p++ = '.'; *p++ = CR; *p = LF; - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability; + size = ngx_mail_pop3_auth_capability.len + 3; - } else { - conf->auth_capability = ngx_mail_pop3_auth_plain_capability; + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + size += ngx_mail_pop3_auth_methods_authnames[i].len; + } } + p = ngx_pnalloc(cf->pool, size); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + conf->auth_capability.data = p; + conf->auth_capability.len = size; + + p = ngx_cpymem(p, ngx_mail_pop3_auth_capability.data, + ngx_mail_pop3_auth_capability.len); + + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_authnames[i].data, + ngx_mail_pop3_auth_methods_authnames[i].len); + } + } + *p++ = '.'; *p++ = CR; *p = LF; + p = ngx_pnalloc(cf->pool, stls_only_size); if (p == NULL) { diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_smtp_handler.c Sat Oct 08 18:05:00 2016 +1100 @@ -485,6 +485,10 @@ case ngx_smtp_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_smtp_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } @@ -652,6 +656,13 @@ } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, smtp_username); + s->mail_state = ngx_smtp_auth_external; + + return NGX_OK; } return rc; diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_smtp_module.c --- a/src/mail/ngx_mail_smtp_module.c Fri Oct 07 16:59:14 2016 +0300 +++ b/src/mail/ngx_mail_smtp_module.c Sat Oct 08 18:05:00 2016 +1100 @@ -21,6 +21,7 @@ { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_string("none"), NGX_MAIL_AUTH_NONE_ENABLED }, { ngx_null_string, 0 } }; @@ -31,6 +32,7 @@ ngx_string("LOGIN"), ngx_null_string, /* APOP */ ngx_string("CRAM-MD5"), + ngx_string("EXTERNAL"), ngx_null_string /* NONE */ }; @@ -207,7 +209,7 @@ auth_enabled = 0; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -250,7 +252,7 @@ *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H'; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { From igor at sysoev.ru Mon Oct 10 12:40:02 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 10 Oct 2016 12:40:02 +0000 Subject: [njs] Now setting property of primitive type returns TypeError e... Message-ID: details: http://hg.nginx.org/njs/rev/769173883f87 branches: changeset: 189:769173883f87 user: Igor Sysoev date: Mon Oct 10 13:08:40 2016 +0300 description: Now setting property of primitive type returns TypeError exception. diffstat: njs/njs_vm.c | 5 +++++ njs/test/njs_unit_test.c | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diffs (50 lines): diff -r 1261cc58591e -r 769173883f87 njs/njs_vm.c --- a/njs/njs_vm.c Tue Oct 04 11:28:29 2016 +0300 +++ b/njs/njs_vm.c Mon Oct 10 13:08:40 2016 +0300 @@ -642,6 +642,11 @@ njs_vmcode_property_set(njs_vm_t *vm, nj njs_property_query_t pq; njs_vmcode_prop_set_t *code; + if (njs_is_primitive(object)) { + vm->exception = &njs_exception_type_error; + return NXT_ERROR; + } + code = (njs_vmcode_prop_set_t *) vm->current; value = njs_vmcode_operand(vm, code->value); diff -r 1261cc58591e -r 769173883f87 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 04 11:28:29 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Oct 10 13:08:40 2016 +0300 @@ -1833,6 +1833,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("a = {}; a.b.c"), nxt_string("TypeError") }, + { nxt_string("'a'.b = 1"), + nxt_string("TypeError") }, + { nxt_string("a = {}; a.b = 1; a.b"), nxt_string("1") }, @@ -1867,10 +1870,10 @@ static njs_unit_test_t njs_test[] = nxt_string("TypeError") }, { nxt_string("a = true; a.b++; a.b"), - nxt_string("undefined") }, + nxt_string("TypeError") }, { nxt_string("a = 1; a.b++; a.b"), - nxt_string("undefined") }, + nxt_string("TypeError") }, { nxt_string("a = {}; a.b = {}; a.b.c = 1; a.b['c']"), nxt_string("1") }, @@ -1885,7 +1888,7 @@ static njs_unit_test_t njs_test[] = nxt_string("2 1") }, { nxt_string("a = 2; a.b = 1; c = a.b++; a +' '+ a.b +' '+ c"), - nxt_string("2 undefined NaN") }, + nxt_string("TypeError") }, { nxt_string("x = { a: 1 }; x.a"), nxt_string("1") }, From mdounin at mdounin.ru Mon Oct 10 13:23:16 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 10 Oct 2016 13:23:16 +0000 Subject: [nginx] Core: sockaddr lengths now respected by ngx_cmp_sockaddr(). Message-ID: details: http://hg.nginx.org/nginx/rev/3f94a0fc05cf branches: changeset: 6731:3f94a0fc05cf user: Maxim Dounin date: Mon Oct 10 16:15:41 2016 +0300 description: Core: sockaddr lengths now respected by ngx_cmp_sockaddr(). Linux can return AF_UNIX sockaddrs with partially filled sun_path, resulting in spurious comparison failures and failed binary upgrades. Added proper checking of the lengths provided. Reported by Jan Seda, http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008832.html. diffstat: src/core/ngx_inet.c | 19 +++++++++++++------ 1 files changed, 13 insertions(+), 6 deletions(-) diffs (39 lines): diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -1364,6 +1364,7 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, s struct sockaddr_in6 *sin61, *sin62; #endif #if (NGX_HAVE_UNIX_DOMAIN) + size_t len; struct sockaddr_un *saun1, *saun2; #endif @@ -1393,15 +1394,21 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, s #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: - /* TODO length */ - saun1 = (struct sockaddr_un *) sa1; saun2 = (struct sockaddr_un *) sa2; - if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path, - sizeof(saun1->sun_path)) - != 0) - { + if (slen1 < slen2) { + len = slen1 - offsetof(struct sockaddr_un, sun_path); + + } else { + len = slen2 - offsetof(struct sockaddr_un, sun_path); + } + + if (len > sizeof(saun1->sun_path)) { + len = sizeof(saun1->sun_path); + } + + if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path, len) != 0) { return NGX_DECLINED; } From mdounin at mdounin.ru Mon Oct 10 13:29:23 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 10 Oct 2016 13:29:23 +0000 Subject: [nginx] Allowed '-' in method names. Message-ID: details: http://hg.nginx.org/nginx/rev/57148b755320 branches: changeset: 6732:57148b755320 user: Maxim Dounin date: Mon Oct 10 16:24:50 2016 +0300 description: Allowed '-' in method names. It is used at least by SOAP (M-POST method, defined by RFC 2774) and by WebDAV versioning (VERSION-CONTROL and BASELINE-CONTROL methods, defined by RFC 3253). diffstat: src/http/ngx_http_parse.c | 4 ++-- src/http/v2/ngx_http_v2.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diffs (33 lines): diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -149,7 +149,7 @@ ngx_http_parse_request_line(ngx_http_req break; } - if ((ch < 'A' || ch > 'Z') && ch != '_') { + if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') { return NGX_HTTP_PARSE_INVALID_METHOD; } @@ -270,7 +270,7 @@ ngx_http_parse_request_line(ngx_http_req break; } - if ((ch < 'A' || ch > 'Z') && ch != '_') { + if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') { return NGX_HTTP_PARSE_INVALID_METHOD; } diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -3178,7 +3178,7 @@ ngx_http_v2_parse_method(ngx_http_reques p = r->method_name.data; do { - if ((*p < 'A' || *p > 'Z') && *p != '_') { + if ((*p < 'A' || *p > 'Z') && *p != '_' && *p != '-') { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent invalid method: \"%V\"", &r->method_name); From igor at sysoev.ru Mon Oct 10 14:20:24 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 10 Oct 2016 14:20:24 +0000 Subject: [njs] Now njs_vm_compile() returns all global functions via the ... Message-ID: details: http://hg.nginx.org/njs/rev/03d12ab0961e branches: changeset: 190:03d12ab0961e user: Igor Sysoev date: Mon Oct 10 16:33:56 2016 +0300 description: Now njs_vm_compile() returns all global functions via the export array. diffstat: nginx/ngx_http_js_module.c | 4 +- nginx/ngx_stream_js_module.c | 4 +- njs/njs_variable.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ njs/njs_variable.h | 7 +++++ njs/njscript.c | 7 ++++- njs/njscript.h | 2 +- njs/test/njs_unit_test.c | 8 ++-- 7 files changed, 81 insertions(+), 10 deletions(-) diffs (207 lines): diff -r 769173883f87 -r 03d12ab0961e nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Mon Oct 10 13:08:40 2016 +0300 +++ b/nginx/ngx_http_js_module.c Mon Oct 10 16:33:56 2016 +0300 @@ -1225,7 +1225,7 @@ ngx_http_js_include(ngx_conf_t *cf, ngx_ ngx_fd_t fd; ngx_str_t *value, file; nxt_int_t rc; - nxt_str_t text, ext; + nxt_str_t text, ext, *export; nxt_lvlhsh_t externals; ngx_file_info_t fi; njs_vm_shared_t *shared; @@ -1321,7 +1321,7 @@ ngx_http_js_include(ngx_conf_t *cf, ngx_ return NGX_CONF_ERROR; } - rc = njs_vm_compile(jlcf->vm, &start, end, NULL); + rc = njs_vm_compile(jlcf->vm, &start, end, NULL, &export); if (rc != NJS_OK) { njs_vm_exception(jlcf->vm, &text); diff -r 769173883f87 -r 03d12ab0961e nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c Mon Oct 10 13:08:40 2016 +0300 +++ b/nginx/ngx_stream_js_module.c Mon Oct 10 16:33:56 2016 +0300 @@ -933,7 +933,7 @@ ngx_stream_js_include(ngx_conf_t *cf, ng ngx_fd_t fd; ngx_str_t *value, file; nxt_int_t rc; - nxt_str_t text, ext; + nxt_str_t text, ext, *export; nxt_lvlhsh_t externals; ngx_file_info_t fi; njs_vm_shared_t *shared; @@ -1029,7 +1029,7 @@ ngx_stream_js_include(ngx_conf_t *cf, ng return NGX_CONF_ERROR; } - rc = njs_vm_compile(jscf->vm, &start, end, NULL); + rc = njs_vm_compile(jscf->vm, &start, end, NULL, &export); if (rc != NJS_OK) { njs_vm_exception(jscf->vm, &text); diff -r 769173883f87 -r 03d12ab0961e njs/njs_variable.c --- a/njs/njs_variable.c Mon Oct 10 13:08:40 2016 +0300 +++ b/njs/njs_variable.c Mon Oct 10 16:33:56 2016 +0300 @@ -153,6 +153,65 @@ njs_parser_variable(njs_vm_t *vm, njs_pa } +nxt_str_t * +njs_vm_export_functions(njs_vm_t *vm) +{ + size_t n; + nxt_str_t *ex, *export; + njs_value_t *value; + njs_variable_t *var; + nxt_lvlhsh_each_t lhe; + + n = 1; + + memset(&lhe, 0, sizeof(nxt_lvlhsh_each_t)); + lhe.proto = &njs_variables_hash_proto; + + for ( ;; ) { + var = nxt_lvlhsh_each(&vm->variables_hash, &lhe); + if (var == NULL) { + break; + } + + value = njs_global_variable_value(vm, var); + + if (njs_is_function(value) && !value->data.u.function->native) { + n++; + } + } + + export = nxt_mem_cache_alloc(vm->mem_cache_pool, n * sizeof(nxt_str_t)); + if (nxt_slow_path(export == NULL)) { + return NULL; + } + + memset(&lhe, 0, sizeof(nxt_lvlhsh_each_t)); + lhe.proto = &njs_variables_hash_proto; + + ex = export; + + for ( ;; ) { + var = nxt_lvlhsh_each(&vm->variables_hash, &lhe); + if (var == NULL) { + break; + } + + value = njs_global_variable_value(vm, var); + + if (njs_is_function(value) && !value->data.u.function->native) { + ex->length = var->name_len; + ex->start = var->name_start; + ex++; + } + } + + ex->length = 0; + ex->start = NULL; + + return export; +} + + njs_function_t * njs_vm_function(njs_vm_t *vm, nxt_str_t *name) { diff -r 769173883f87 -r 03d12ab0961e njs/njs_variable.h --- a/njs/njs_variable.h Mon Oct 10 13:08:40 2016 +0300 +++ b/njs/njs_variable.h Mon Oct 10 16:33:56 2016 +0300 @@ -26,10 +26,17 @@ typedef struct { } njs_variable_t; +#define njs_global_variable_value(vm, var) \ + (njs_value_t *) ((u_char *) vm->global_scope \ + + njs_offset((var)->index) - NJS_INDEX_GLOBAL_OFFSET) + + + njs_variable_t *njs_parser_name_alloc(njs_vm_t *vm, njs_parser_t *parser); njs_variable_t *njs_parser_variable(njs_vm_t *vm, njs_parser_t *parser, nxt_uint_t *level); njs_value_t *njs_variable_value(njs_parser_t *parser, njs_index_t index); +nxt_str_t *njs_vm_export_functions(njs_vm_t *vm); #endif /* _NJS_VARIABLE_H_INCLUDED_ */ diff -r 769173883f87 -r 03d12ab0961e njs/njscript.c --- a/njs/njscript.c Mon Oct 10 13:08:40 2016 +0300 +++ b/njs/njscript.c Mon Oct 10 16:33:56 2016 +0300 @@ -175,7 +175,7 @@ njs_vm_destroy(njs_vm_t *vm) nxt_int_t njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end, - njs_function_t **function) + njs_function_t **function, nxt_str_t **export) { nxt_int_t ret; njs_lexer_t *lexer; @@ -251,6 +251,11 @@ njs_vm_compile(njs_vm_t *vm, u_char **st vm->parser = NULL; + *export = njs_vm_export_functions(vm); + if (nxt_slow_path(*export == NULL)) { + return NJS_ERROR; + } + return NJS_OK; } diff -r 769173883f87 -r 03d12ab0961e njs/njscript.h --- a/njs/njscript.h Mon Oct 10 13:08:40 2016 +0300 +++ b/njs/njscript.h Mon Oct 10 16:33:56 2016 +0300 @@ -84,7 +84,7 @@ NXT_EXPORT njs_vm_t *njs_vm_create(nxt_m NXT_EXPORT void njs_vm_destroy(njs_vm_t *vm); NXT_EXPORT nxt_int_t njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end, - njs_function_t **function); + njs_function_t **function, nxt_str_t **export); NXT_EXPORT njs_vm_t *njs_vm_clone(njs_vm_t *vm, nxt_mem_cache_pool_t *mcp, void **external); NXT_EXPORT nxt_int_t njs_vm_call(njs_vm_t *vm, njs_function_t *function, diff -r 769173883f87 -r 03d12ab0961e njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 10 13:08:40 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Oct 10 16:33:56 2016 +0300 @@ -5484,7 +5484,7 @@ njs_unit_test(nxt_bool_t disassemble) u_char *start; njs_vm_t *vm, *nvm; nxt_int_t ret; - nxt_str_t s, r_name; + nxt_str_t s, r_name, *export; nxt_uint_t i; nxt_bool_t success; nxt_lvlhsh_t externals; @@ -5532,7 +5532,7 @@ njs_unit_test(nxt_bool_t disassemble) start = njs_test[i].script.start; ret = njs_vm_compile(vm, &start, start + njs_test[i].script.length, - &function); + &function, &export); if (ret == NXT_OK) { if (disassemble) { @@ -5611,7 +5611,7 @@ njs_unit_test_benchmark(nxt_str_t *scrip njs_vm_t *vm, *nvm; uint64_t us; nxt_int_t ret; - nxt_str_t s; + nxt_str_t s, *export; nxt_uint_t i; nxt_bool_t success; nxt_lvlhsh_t externals; @@ -5645,7 +5645,7 @@ njs_unit_test_benchmark(nxt_str_t *scrip start = script->start; - ret = njs_vm_compile(vm, &start, start + script->length, NULL); + ret = njs_vm_compile(vm, &start, start + script->length, NULL, &export); if (ret != NXT_OK) { return NXT_ERROR; } From igor at sysoev.ru Mon Oct 10 14:22:51 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 10 Oct 2016 14:22:51 +0000 Subject: [njs] Version 0.1.3. Message-ID: details: http://hg.nginx.org/njs/rev/360449773d51 branches: changeset: 191:360449773d51 user: Igor Sysoev date: Mon Oct 10 17:21:53 2016 +0300 description: Version 0.1.3. diffstat: Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (10 lines): diff -r 03d12ab0961e -r 360449773d51 Makefile --- a/Makefile Mon Oct 10 16:33:56 2016 +0300 +++ b/Makefile Mon Oct 10 17:21:53 2016 +0300 @@ -1,5 +1,5 @@ -NJS_VER = 0.1.2 +NJS_VER = 0.1.3 NXT_LIB = nxt From igor at sysoev.ru Mon Oct 10 14:22:53 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 10 Oct 2016 14:22:53 +0000 Subject: [njs] Added tag 0.1.3 for changeset 360449773d51 Message-ID: details: http://hg.nginx.org/njs/rev/aa8137bb7838 branches: changeset: 192:aa8137bb7838 user: Igor Sysoev date: Mon Oct 10 17:22:26 2016 +0300 description: Added tag 0.1.3 for changeset 360449773d51 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 360449773d51 -r aa8137bb7838 .hgtags --- a/.hgtags Mon Oct 10 17:21:53 2016 +0300 +++ b/.hgtags Mon Oct 10 17:22:26 2016 +0300 @@ -1,3 +1,4 @@ cdb8d20935ee96f1fa0c99d994d4b11cefcbc119 0.1.0 0039a747d25a3e08792c23c43b75768896724031 0.1.1 5b066b4db54c17dc0a9a72948474f36957462e87 0.1.2 +360449773d51e7f451e5396e27021badc6b86085 0.1.3 From mdounin at mdounin.ru Mon Oct 10 16:51:44 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 10 Oct 2016 16:51:44 +0000 Subject: [nginx] Modules compatibility: compatibility with NGX_THREADS. Message-ID: details: http://hg.nginx.org/nginx/rev/adc2414856b1 branches: changeset: 6733:adc2414856b1 user: Maxim Dounin date: Mon Oct 10 18:44:17 2016 +0300 description: Modules compatibility: compatibility with NGX_THREADS. With this change it is now possible to load modules compiled without the "--with-threads" configure option into nginx binary compiled with it, and vice versa (if a module does not use thread-specific functions), assuming both use the "--with-compat" option. diffstat: src/core/ngx_buf.h | 4 +--- src/core/ngx_connection.h | 2 +- src/core/ngx_core.h | 27 ++++++++++++--------------- src/core/ngx_file.h | 2 +- src/core/ngx_module.h | 2 +- src/event/ngx_event_pipe.h | 2 +- src/http/ngx_http_cache.h | 2 +- src/http/ngx_http_core_module.h | 4 +++- 8 files changed, 21 insertions(+), 24 deletions(-) diffs (141 lines): diff --git a/src/core/ngx_buf.h b/src/core/ngx_buf.h --- a/src/core/ngx_buf.h +++ b/src/core/ngx_buf.h @@ -88,9 +88,7 @@ struct ngx_output_chain_ctx_s { unsigned unaligned:1; unsigned need_in_memory:1; unsigned need_in_temp:1; -#if (NGX_HAVE_FILE_AIO || NGX_THREADS) unsigned aio:1; -#endif #if (NGX_HAVE_FILE_AIO) ngx_output_chain_aio_pt aio_handler; @@ -99,7 +97,7 @@ struct ngx_output_chain_ctx_s { #endif #endif -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_int_t (*thread_handler)(ngx_thread_task_t *task, ngx_file_t *file); ngx_thread_task_t *thread_task; diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -186,7 +186,7 @@ struct ngx_connection_s { unsigned busy_count:2; #endif -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_thread_task_t *sendfile_task; #endif }; diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -12,22 +12,19 @@ #include -typedef struct ngx_module_s ngx_module_t; -typedef struct ngx_conf_s ngx_conf_t; -typedef struct ngx_cycle_s ngx_cycle_t; -typedef struct ngx_pool_s ngx_pool_t; -typedef struct ngx_chain_s ngx_chain_t; -typedef struct ngx_log_s ngx_log_t; -typedef struct ngx_open_file_s ngx_open_file_t; -typedef struct ngx_command_s ngx_command_t; -typedef struct ngx_file_s ngx_file_t; -typedef struct ngx_event_s ngx_event_t; -typedef struct ngx_event_aio_s ngx_event_aio_t; -typedef struct ngx_connection_s ngx_connection_t; - -#if (NGX_THREADS) +typedef struct ngx_module_s ngx_module_t; +typedef struct ngx_conf_s ngx_conf_t; +typedef struct ngx_cycle_s ngx_cycle_t; +typedef struct ngx_pool_s ngx_pool_t; +typedef struct ngx_chain_s ngx_chain_t; +typedef struct ngx_log_s ngx_log_t; +typedef struct ngx_open_file_s ngx_open_file_t; +typedef struct ngx_command_s ngx_command_t; +typedef struct ngx_file_s ngx_file_t; +typedef struct ngx_event_s ngx_event_t; +typedef struct ngx_event_aio_s ngx_event_aio_t; +typedef struct ngx_connection_s ngx_connection_t; typedef struct ngx_thread_task_s ngx_thread_task_t; -#endif typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -23,7 +23,7 @@ struct ngx_file_s { ngx_log_t *log; -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_int_t (*thread_handler)(ngx_thread_task_t *task, ngx_file_t *file); void *thread_ctx; diff --git a/src/core/ngx_module.h b/src/core/ngx_module.h --- a/src/core/ngx_module.h +++ b/src/core/ngx_module.h @@ -127,7 +127,7 @@ #define NGX_MODULE_SIGNATURE_21 "0" #endif -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_22 "1" #else #define NGX_MODULE_SIGNATURE_22 "0" diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h --- a/src/event/ngx_event_pipe.h +++ b/src/event/ngx_event_pipe.h @@ -47,7 +47,7 @@ struct ngx_event_pipe_s { ngx_event_pipe_output_filter_pt output_filter; void *output_ctx; -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_int_t (*thread_handler)(ngx_thread_task_t *task, ngx_file_t *file); void *thread_ctx; 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 @@ -93,7 +93,7 @@ struct ngx_http_cache_s { ngx_http_file_cache_t *file_cache; ngx_http_file_cache_node_t *node; -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_thread_task_t *thread_task; #endif diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -15,6 +15,8 @@ #if (NGX_THREADS) #include +#elif (NGX_COMPAT) +typedef struct ngx_thread_pool_s ngx_thread_pool_t; #endif @@ -409,7 +411,7 @@ struct ngx_http_core_loc_conf_s { #endif #endif -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_thread_pool_t *thread_pool; ngx_http_complex_value_t *thread_pool_value; #endif From mdounin at mdounin.ru Mon Oct 10 16:51:47 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 10 Oct 2016 16:51:47 +0000 Subject: [nginx] Modules compatibility: compatibility with NGX_HAVE_FILE_AIO. Message-ID: details: http://hg.nginx.org/nginx/rev/0c572ed91b36 branches: changeset: 6734:0c572ed91b36 user: Maxim Dounin date: Mon Oct 10 18:44:17 2016 +0300 description: Modules compatibility: compatibility with NGX_HAVE_FILE_AIO. With this change it is now possible to load modules compiled without the "--with-file-aio" configure option into nginx binary compiled with it, and vice versa, assuming both use the "--with-compat" option. diffstat: src/core/ngx_buf.h | 6 ++---- src/core/ngx_connection.h | 2 +- src/core/ngx_file.h | 2 +- src/core/ngx_module.h | 4 ++-- src/event/ngx_event.h | 2 +- src/http/ngx_http_core_module.c | 2 -- 6 files changed, 7 insertions(+), 11 deletions(-) diffs (95 lines): diff --git a/src/core/ngx_buf.h b/src/core/ngx_buf.h --- a/src/core/ngx_buf.h +++ b/src/core/ngx_buf.h @@ -72,10 +72,8 @@ typedef struct ngx_output_chain_ctx_s n typedef ngx_int_t (*ngx_output_chain_filter_pt)(void *ctx, ngx_chain_t *in); -#if (NGX_HAVE_FILE_AIO) typedef void (*ngx_output_chain_aio_pt)(ngx_output_chain_ctx_t *ctx, ngx_file_t *file); -#endif struct ngx_output_chain_ctx_s { ngx_buf_t *buf; @@ -90,9 +88,9 @@ struct ngx_output_chain_ctx_s { unsigned need_in_temp:1; unsigned aio:1; -#if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_FILE_AIO || NGX_COMPAT) ngx_output_chain_aio_pt aio_handler; -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) ssize_t (*aio_preload)(ngx_buf_t *file); #endif #endif diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -182,7 +182,7 @@ struct ngx_connection_s { unsigned need_last_buf:1; -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) unsigned busy_count:2; #endif diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -30,7 +30,7 @@ struct ngx_file_s { ngx_thread_task_t *thread_task; #endif -#if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_FILE_AIO || NGX_COMPAT) ngx_event_aio_t *aio; #endif diff --git a/src/core/ngx_module.h b/src/core/ngx_module.h --- a/src/core/ngx_module.h +++ b/src/core/ngx_module.h @@ -35,13 +35,13 @@ #define NGX_MODULE_SIGNATURE_2 "0" #endif -#if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_FILE_AIO || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_3 "1" #else #define NGX_MODULE_SIGNATURE_3 "0" #endif -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_4 "1" #else #define NGX_MODULE_SIGNATURE_4 "0" diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -152,7 +152,7 @@ struct ngx_event_aio_s { ngx_event_handler_pt handler; ngx_file_t *file; -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) ssize_t (*preload_handler)(ngx_buf_t *file); #endif diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -3760,10 +3760,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); ngx_conf_merge_size_value(conf->sendfile_max_chunk, prev->sendfile_max_chunk, 0); -#if (NGX_HAVE_FILE_AIO || NGX_THREADS) ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF); ngx_conf_merge_value(conf->aio_write, prev->aio_write, 0); -#endif #if (NGX_THREADS) ngx_conf_merge_ptr_value(conf->thread_pool, prev->thread_pool, NULL); ngx_conf_merge_ptr_value(conf->thread_pool_value, prev->thread_pool_value, From mdounin at mdounin.ru Mon Oct 10 16:51:50 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 10 Oct 2016 16:51:50 +0000 Subject: [nginx] Modules compatibility: compatibility with NGX_HTTP_SSL. Message-ID: details: http://hg.nginx.org/nginx/rev/e38e9c50a40e branches: changeset: 6735:e38e9c50a40e user: Maxim Dounin date: Mon Oct 10 18:44:17 2016 +0300 description: Modules compatibility: compatibility with NGX_HTTP_SSL. With this change it is now possible to load modules compiled without the "--with-http_ssl_module" configure option into nginx binary compiled with it, and vice versa (if a module doesn't use ssl-specific functions), assuming both use the "--with-compat" option. diffstat: src/core/ngx_connection.h | 2 +- src/core/ngx_core.h | 28 +++++++++++++++------------- src/core/ngx_module.h | 2 +- src/event/ngx_event_connect.h | 5 +---- src/event/ngx_event_openssl.h | 8 ++++---- src/http/ngx_http_core_module.h | 4 ---- src/http/ngx_http_request.h | 4 +--- src/http/ngx_http_upstream.h | 4 ++-- src/http/ngx_http_upstream_round_robin.h | 2 +- 9 files changed, 26 insertions(+), 33 deletions(-) diffs (196 lines): diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -147,7 +147,7 @@ struct ngx_connection_s { ngx_str_t proxy_protocol_addr; in_port_t proxy_protocol_port; -#if (NGX_SSL) +#if (NGX_SSL || NGX_COMPAT) ngx_ssl_connection_t *ssl; #endif diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -12,19 +12,21 @@ #include -typedef struct ngx_module_s ngx_module_t; -typedef struct ngx_conf_s ngx_conf_t; -typedef struct ngx_cycle_s ngx_cycle_t; -typedef struct ngx_pool_s ngx_pool_t; -typedef struct ngx_chain_s ngx_chain_t; -typedef struct ngx_log_s ngx_log_t; -typedef struct ngx_open_file_s ngx_open_file_t; -typedef struct ngx_command_s ngx_command_t; -typedef struct ngx_file_s ngx_file_t; -typedef struct ngx_event_s ngx_event_t; -typedef struct ngx_event_aio_s ngx_event_aio_t; -typedef struct ngx_connection_s ngx_connection_t; -typedef struct ngx_thread_task_s ngx_thread_task_t; +typedef struct ngx_module_s ngx_module_t; +typedef struct ngx_conf_s ngx_conf_t; +typedef struct ngx_cycle_s ngx_cycle_t; +typedef struct ngx_pool_s ngx_pool_t; +typedef struct ngx_chain_s ngx_chain_t; +typedef struct ngx_log_s ngx_log_t; +typedef struct ngx_open_file_s ngx_open_file_t; +typedef struct ngx_command_s ngx_command_t; +typedef struct ngx_file_s ngx_file_t; +typedef struct ngx_event_s ngx_event_t; +typedef struct ngx_event_aio_s ngx_event_aio_t; +typedef struct ngx_connection_s ngx_connection_t; +typedef struct ngx_thread_task_s ngx_thread_task_t; +typedef struct ngx_ssl_s ngx_ssl_t; +typedef struct ngx_ssl_connection_s ngx_ssl_connection_t; typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); diff --git a/src/core/ngx_module.h b/src/core/ngx_module.h --- a/src/core/ngx_module.h +++ b/src/core/ngx_module.h @@ -139,7 +139,7 @@ #define NGX_MODULE_SIGNATURE_23 "0" #endif -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_24 "1" #else #define NGX_MODULE_SIGNATURE_24 "0" diff --git a/src/event/ngx_event_connect.h b/src/event/ngx_event_connect.h --- a/src/event/ngx_event_connect.h +++ b/src/event/ngx_event_connect.h @@ -27,13 +27,10 @@ typedef void (*ngx_event_free_peer_pt)(n ngx_uint_t state); typedef void (*ngx_event_notify_peer_pt)(ngx_peer_connection_t *pc, void *data, ngx_uint_t type); -#if (NGX_SSL) - typedef ngx_int_t (*ngx_event_set_peer_session_pt)(ngx_peer_connection_t *pc, void *data); typedef void (*ngx_event_save_peer_session_pt)(ngx_peer_connection_t *pc, void *data); -#endif struct ngx_peer_connection_s { @@ -51,7 +48,7 @@ struct ngx_peer_connection_s { ngx_event_notify_peer_pt notify; void *data; -#if (NGX_SSL) +#if (NGX_SSL || NGX_COMPAT) ngx_event_set_peer_session_pt set_session; ngx_event_save_peer_session_pt save_session; #endif 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 @@ -54,14 +54,14 @@ #define ngx_ssl_conn_t SSL -typedef struct { +struct ngx_ssl_s { SSL_CTX *ctx; ngx_log_t *log; size_t buffer_size; -} ngx_ssl_t; +}; -typedef struct { +struct ngx_ssl_connection_s { ngx_ssl_conn_t *connection; SSL_CTX *session_ctx; @@ -80,7 +80,7 @@ typedef struct { unsigned no_wait_shutdown:1; unsigned no_send_shutdown:1; unsigned handshake_buffer_set:1; -} ngx_ssl_connection_t; +}; #define NGX_SSL_NO_SCACHE -2 diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -67,9 +67,7 @@ typedef struct { unsigned default_server:1; unsigned bind:1; unsigned wildcard:1; -#if (NGX_HTTP_SSL) unsigned ssl:1; -#endif unsigned http2:1; #if (NGX_HAVE_INET6) unsigned ipv6only:1; @@ -230,9 +228,7 @@ struct ngx_http_addr_conf_s { ngx_http_virtual_names_t *virtual_names; -#if (NGX_HTTP_SSL) unsigned ssl:1; -#endif unsigned http2:1; unsigned proxy_protocol:1; }; diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -300,7 +300,7 @@ typedef struct { ngx_http_addr_conf_t *addr_conf; ngx_http_conf_ctx_t *conf_ctx; -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) ngx_str_t *ssl_servername; #if (NGX_PCRE) ngx_http_regex_t *ssl_servername_regex; @@ -313,9 +313,7 @@ typedef struct { ngx_buf_t **free; ngx_int_t nfree; -#if (NGX_HTTP_SSL) unsigned ssl:1; -#endif unsigned proxy_protocol:1; } ngx_http_connection_t; diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -222,7 +222,7 @@ typedef struct { unsigned intercept_404:1; unsigned change_buffering:1; -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) ngx_ssl_t *ssl; ngx_flag_t ssl_session_reuse; @@ -367,7 +367,7 @@ struct ngx_http_upstream_s { ngx_str_t schema; ngx_str_t uri; -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) ngx_str_t ssl_name; #endif diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h --- a/src/http/ngx_http_upstream_round_robin.h +++ b/src/http/ngx_http_upstream_round_robin.h @@ -40,7 +40,7 @@ struct ngx_http_upstream_rr_peer_s { ngx_uint_t down; -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) void *ssl_session; int ssl_session_len; #endif From mdounin at mdounin.ru Mon Oct 10 16:51:53 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 10 Oct 2016 16:51:53 +0000 Subject: [nginx] Modules compatibility: removed dependencies on NGX_STREAM_SSL. Message-ID: details: http://hg.nginx.org/nginx/rev/f41c2530dd17 branches: changeset: 6736:f41c2530dd17 user: Maxim Dounin date: Mon Oct 10 18:44:17 2016 +0300 description: Modules compatibility: removed dependencies on NGX_STREAM_SSL. External structures are now identical regardless of stream SSL module compiled in or not. diffstat: src/stream/ngx_stream.c | 2 -- src/stream/ngx_stream.h | 8 -------- src/stream/ngx_stream_upstream.h | 2 -- src/stream/ngx_stream_upstream_round_robin.h | 2 -- 4 files changed, 0 insertions(+), 14 deletions(-) diffs (88 lines): diff --git a/src/stream/ngx_stream.c b/src/stream/ngx_stream.c --- a/src/stream/ngx_stream.c +++ b/src/stream/ngx_stream.c @@ -293,14 +293,12 @@ ngx_stream_init_phases(ngx_conf_t *cf, n return NGX_ERROR; } -#if (NGX_STREAM_SSL) if (ngx_array_init(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers, cf->pool, 1, sizeof(ngx_stream_handler_pt)) != NGX_OK) { return NGX_ERROR; } -#endif if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREREAD_PHASE].handlers, cf->pool, 1, sizeof(ngx_stream_handler_pt)) diff --git a/src/stream/ngx_stream.h b/src/stream/ngx_stream.h --- a/src/stream/ngx_stream.h +++ b/src/stream/ngx_stream.h @@ -49,9 +49,7 @@ typedef struct { unsigned bind:1; unsigned wildcard:1; -#if (NGX_STREAM_SSL) unsigned ssl:1; -#endif #if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif @@ -71,9 +69,7 @@ typedef struct { typedef struct { ngx_stream_conf_ctx_t *ctx; ngx_str_t addr_text; -#if (NGX_STREAM_SSL) unsigned ssl:1; -#endif unsigned proxy_protocol:1; } ngx_stream_addr_conf_t; @@ -117,9 +113,7 @@ typedef enum { NGX_STREAM_POST_ACCEPT_PHASE = 0, NGX_STREAM_PREACCESS_PHASE, NGX_STREAM_ACCESS_PHASE, -#if (NGX_STREAM_SSL) NGX_STREAM_SSL_PHASE, -#endif NGX_STREAM_PREREAD_PHASE, NGX_STREAM_CONTENT_PHASE, NGX_STREAM_LOG_PHASE @@ -223,9 +217,7 @@ struct ngx_stream_session_s { ngx_int_t phase_handler; ngx_uint_t status; -#if (NGX_STREAM_SSL) unsigned ssl:1; -#endif unsigned stat_processing:1; diff --git a/src/stream/ngx_stream_upstream.h b/src/stream/ngx_stream_upstream.h --- a/src/stream/ngx_stream_upstream.h +++ b/src/stream/ngx_stream_upstream.h @@ -126,9 +126,7 @@ typedef struct { time_t start_sec; ngx_uint_t responses; -#if (NGX_STREAM_SSL) ngx_str_t ssl_name; -#endif ngx_stream_upstream_srv_conf_t *upstream; ngx_stream_upstream_resolved_t *resolved; diff --git a/src/stream/ngx_stream_upstream_round_robin.h b/src/stream/ngx_stream_upstream_round_robin.h --- a/src/stream/ngx_stream_upstream_round_robin.h +++ b/src/stream/ngx_stream_upstream_round_robin.h @@ -40,10 +40,8 @@ struct ngx_stream_upstream_rr_peer_s { ngx_uint_t down; -#if (NGX_STREAM_SSL) void *ssl_session; int ssl_session_len; -#endif #if (NGX_STREAM_UPSTREAM_ZONE) ngx_atomic_t lock; From mdounin at mdounin.ru Mon Oct 10 16:51:55 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 10 Oct 2016 16:51:55 +0000 Subject: [nginx] Modules compatibility: removed dependencies on NGX_MAIL_SSL. Message-ID: details: http://hg.nginx.org/nginx/rev/a9a50bb65120 branches: changeset: 6737:a9a50bb65120 user: Maxim Dounin date: Mon Oct 10 18:44:17 2016 +0300 description: Modules compatibility: removed dependencies on NGX_MAIL_SSL. External structures are now identical regardless of mail SSL module compiled in or not. diffstat: src/mail/ngx_mail.h | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diffs (23 lines): diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -35,9 +35,7 @@ typedef struct { unsigned bind:1; unsigned wildcard:1; -#if (NGX_MAIL_SSL) unsigned ssl:1; -#endif #if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif @@ -54,9 +52,7 @@ typedef struct { typedef struct { ngx_mail_conf_ctx_t *ctx; ngx_str_t addr_text; -#if (NGX_MAIL_SSL) ngx_uint_t ssl; /* unsigned ssl:1; */ -#endif } ngx_mail_addr_conf_t; typedef struct { From igor at sysoev.ru Tue Oct 11 14:52:02 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 11 Oct 2016 14:52:02 +0000 Subject: [njs] Segfaults in Date have been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/40a753cefac1 branches: changeset: 193:40a753cefac1 user: Igor Sysoev date: Tue Oct 11 13:01:41 2016 +0300 description: Segfaults in Date have been fixed. diffstat: njs/njs_date.c | 2 ++ njs/test/njs_unit_test.c | 6 ++++++ 2 files changed, 8 insertions(+), 0 deletions(-) diffs (35 lines): diff -r aa8137bb7838 -r 40a753cefac1 njs/njs_date.c --- a/njs/njs_date.c Mon Oct 10 17:22:26 2016 +0300 +++ b/njs/njs_date.c Tue Oct 11 13:01:41 2016 +0300 @@ -108,6 +108,7 @@ njs_date_constructor(njs_vm_t *vm, njs_v for (i = 1; i < n; i++) { if (!njs_is_numeric(&args[i])) { + vm->frame->trap_scratch.data.u.value = &args[i]; return NJS_TRAP_NUMBER_ARG; } @@ -186,6 +187,7 @@ njs_date_utc(njs_vm_t *vm, njs_value_t * for (i = 1; i < n; i++) { if (!njs_is_numeric(&args[i])) { + vm->frame->trap_scratch.data.u.value = &args[i]; return NJS_TRAP_NUMBER_ARG; } diff -r aa8137bb7838 -r 40a753cefac1 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 10 17:22:26 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 11 13:01:41 2016 +0300 @@ -5030,6 +5030,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("var d = new Date(); d.__proto__ === Date.prototype"), nxt_string("true") }, + { nxt_string("new Date(eval)"), + nxt_string("Invalid Date") }, + + { nxt_string("Date.UTC(eval)"), + nxt_string("NaN") }, + { nxt_string("Date.name"), nxt_string("Date") }, From igor at sysoev.ru Tue Oct 11 14:52:04 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 11 Oct 2016 14:52:04 +0000 Subject: [njs] Segfaults in increment and decrement operators have been f... Message-ID: details: http://hg.nginx.org/njs/rev/da89f264af94 branches: changeset: 194:da89f264af94 user: Igor Sysoev date: Tue Oct 11 17:04:28 2016 +0300 description: Segfaults in increment and decrement operators have been fixed. diffstat: njs/njs_generator.c | 4 +++- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 6 insertions(+), 1 deletions(-) diffs (34 lines): diff -r 40a753cefac1 -r da89f264af94 njs/njs_generator.c --- a/njs/njs_generator.c Tue Oct 11 13:01:41 2016 +0300 +++ b/njs/njs_generator.c Tue Oct 11 17:04:28 2016 +0300 @@ -21,6 +21,7 @@ #include #include #include +#include static nxt_int_t njs_generator(njs_vm_t *vm, njs_parser_t *parser, @@ -1848,7 +1849,8 @@ njs_generate_inc_dec_operation(njs_vm_t if (node->dest != NULL) { dest_index = node->dest->index; - if (dest_index != lvalue->left->index + if (dest_index != NJS_INDEX_NONE + && dest_index != lvalue->left->index && dest_index != lvalue->right->index) { node->index = dest_index; diff -r 40a753cefac1 -r da89f264af94 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 11 13:01:41 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 11 17:04:28 2016 +0300 @@ -471,6 +471,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("[[]+[]]-[]+[[]-[]]"), nxt_string("00") }, + { nxt_string("!--[][1]"), + nxt_string("true") }, + { nxt_string("'true' == true"), nxt_string("false") }, From igor at sysoev.ru Tue Oct 11 14:52:05 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 11 Oct 2016 14:52:05 +0000 Subject: [njs] Segfaults in the delete operator have been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/f8cc880d9b9b branches: changeset: 195:f8cc880d9b9b user: Igor Sysoev date: Tue Oct 11 17:44:01 2016 +0300 description: Segfaults in the delete operator have been fixed. diffstat: njs/njs_generator.c | 77 --------------------------------------------- njs/njs_parser_expression.c | 34 +++++++++++++------ njs/njs_vm.c | 2 - njs/test/njs_unit_test.c | 27 +++++++++----- 4 files changed, 40 insertions(+), 100 deletions(-) diffs (225 lines): diff -r da89f264af94 -r f8cc880d9b9b njs/njs_generator.c --- a/njs/njs_generator.c Tue Oct 11 17:04:28 2016 +0300 +++ b/njs/njs_generator.c Tue Oct 11 17:44:01 2016 +0300 @@ -21,7 +21,6 @@ #include #include #include -#include static nxt_int_t njs_generator(njs_vm_t *vm, njs_parser_t *parser, @@ -76,8 +75,6 @@ static nxt_int_t njs_generate_function(n njs_parser_node_t *node); static nxt_int_t njs_generate_regexp(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node); -static nxt_int_t njs_generate_delete(njs_vm_t *vm, njs_parser_t *parser, - njs_parser_node_t *node); static nxt_int_t njs_generate_test_jump_expression(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node); static nxt_int_t njs_generate_3addr_operation(njs_vm_t *vm, @@ -232,8 +229,6 @@ njs_generator(njs_vm_t *vm, njs_parser_t return njs_generate_test_jump_expression(vm, parser, node); case NJS_TOKEN_DELETE: - return njs_generate_delete(vm, parser, node); - case NJS_TOKEN_VOID: case NJS_TOKEN_TYPEOF: case NJS_TOKEN_UNARY_PLUS: @@ -1578,78 +1573,6 @@ njs_generate_regexp(njs_vm_t *vm, njs_pa static nxt_int_t -njs_generate_delete(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node) -{ - double n; - nxt_int_t ret; - njs_index_t index; - njs_parser_node_t *operand; - njs_vmcode_2addr_t *delete; - - operand = node->left; - - /* - * The "delete" operator returns "false" for "undefined", "NaN", and - * "Infinity" constants but not for values, expressions and "-Infinity". - */ - - switch (operand->token) { - - case NJS_TOKEN_NAME: - if (operand->u.variable->state == NJS_VARIABLE_DECLARED) { - index = njs_value_index(vm, parser, &njs_value_false); - goto done; - } - - /* A property of the global object. */ - - njs_generate_code(parser, njs_vmcode_2addr_t, delete); - delete->code.operation = njs_vmcode_delete; - delete->code.operands = NJS_VMCODE_2OPERANDS; - delete->code.retval = NJS_VMCODE_RETVAL; - delete->dst = njs_generator_node_temp_index_get(parser, node); - delete->src = operand->u.variable->index; - - return NXT_OK; - - case NJS_TOKEN_NUMBER: - n = operand->u.value.data.u.number; - - if (!njs_is_nan(n) && !(njs_is_infinity(n) && n > 0.0)) { - break; - } - - /* Fall through. */ - - case NJS_TOKEN_UNDEFINED: - index = njs_value_index(vm, parser, &njs_value_false); - goto done; - - default: - ret = njs_generator(vm, parser, operand); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - ret = njs_generator_node_index_release(vm, parser, operand); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - - break; - } - - index = njs_value_index(vm, parser, &njs_value_true); - -done: - - node->index = index; - - return NXT_OK; -} - - -static nxt_int_t njs_generate_test_jump_expression(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node) { diff -r da89f264af94 -r f8cc880d9b9b njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Tue Oct 11 17:04:28 2016 +0300 +++ b/njs/njs_parser_expression.c Tue Oct 11 17:44:01 2016 +0300 @@ -749,19 +749,31 @@ njs_parser_unary_expression(njs_vm_t *vm return next; } - if (token == NJS_TOKEN_TYPEOF - && parser->node->token == NJS_TOKEN_NAME) - { - parser->node->state = NJS_VARIABLE_TYPEOF; + if (token == NJS_TOKEN_DELETE) { - } else if (token == NJS_TOKEN_DELETE - && parser->node->token == NJS_TOKEN_PROPERTY) - { - parser->node->token = NJS_TOKEN_PROPERTY_DELETE; - parser->node->u.operation = njs_vmcode_property_delete; - parser->code_size += sizeof(njs_vmcode_3addr_t); + switch (parser->node->token) { - return next; + case NJS_TOKEN_PROPERTY: + parser->node->token = NJS_TOKEN_PROPERTY_DELETE; + parser->node->u.operation = njs_vmcode_property_delete; + parser->code_size += sizeof(njs_vmcode_3addr_t); + + return next; + + case NJS_TOKEN_NAME: + case NJS_TOKEN_UNDEFINED: + nxt_alert(&vm->trace, NXT_LEVEL_ERROR, + "SyntaxError: Delete of an unqualified identifier"); + + return NJS_TOKEN_ILLEGAL; + + default: + break; + } + } + + if (token == NJS_TOKEN_TYPEOF && parser->node->token == NJS_TOKEN_NAME) { + parser->node->state = NJS_VARIABLE_TYPEOF; } node = njs_parser_node_alloc(vm); diff -r da89f264af94 -r f8cc880d9b9b njs/njs_vm.c --- a/njs/njs_vm.c Tue Oct 11 17:04:28 2016 +0300 +++ b/njs/njs_vm.c Tue Oct 11 17:44:01 2016 +0300 @@ -1466,8 +1466,6 @@ njs_vmcode_delete(njs_vm_t *vm, njs_valu { njs_release(vm, value); - njs_set_invalid(value); - vm->retval = njs_value_true; return sizeof(njs_vmcode_2addr_t); diff -r da89f264af94 -r f8cc880d9b9b njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 11 17:04:28 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 11 17:44:01 2016 +0300 @@ -1951,16 +1951,20 @@ static njs_unit_test_t njs_test[] = nxt_string("true") }, { nxt_string("var a; delete a"), - nxt_string("false") }, + nxt_string("SyntaxError: Delete of an unqualified identifier in 1") }, { nxt_string("delete undefined"), - nxt_string("false") }, + nxt_string("SyntaxError: Delete of an unqualified identifier in 1") }, + + /* ES5FIX: "SyntaxError". */ { nxt_string("delete NaN"), - nxt_string("false") }, + nxt_string("true") }, + + /* ES5FIX: "SyntaxError". */ { nxt_string("delete Infinity"), - nxt_string("false") }, + nxt_string("true") }, { nxt_string("delete -Infinity"), nxt_string("true") }, @@ -1971,21 +1975,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("delete 1"), nxt_string("true") }, - { nxt_string("delete (a = 1); a"), + { nxt_string("var a; delete (a = 1); a"), nxt_string("1") }, { nxt_string("delete a"), - nxt_string("true") }, + nxt_string("SyntaxError: Delete of an unqualified identifier in 1") }, { nxt_string("a = 1; delete a"), - nxt_string("true") }, - - { nxt_string("a = 1; delete a; typeof a"), - nxt_string("undefined") }, + nxt_string("SyntaxError: Delete of an unqualified identifier in 1") }, + + { nxt_string("function f(){} delete f"), + nxt_string("SyntaxError: Delete of an unqualified identifier in 1") }, { nxt_string("a = { x:1 }; ('x' in a) +' '+ (1 in a)"), nxt_string("true false") }, + { nxt_string("delete --[][1]"), + nxt_string("true") }, + { nxt_string("a = {}; 1 in a"), nxt_string("false") }, From igor at sysoev.ru Tue Oct 11 14:52:06 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 11 Oct 2016 14:52:06 +0000 Subject: [njs] Accessing the global this object caused segfault. Message-ID: details: http://hg.nginx.org/njs/rev/a3588250473b branches: changeset: 196:a3588250473b user: Igor Sysoev date: Tue Oct 11 17:44:05 2016 +0300 description: Accessing the global this object caused segfault. diffstat: njs/njs_builtin.c | 17 ++++++++++------- njs/njs_generator.c | 1 + njs/njs_parser.c | 10 ++++++++-- njs/njs_parser.h | 3 ++- njs/njs_vm.h | 3 ++- njs/test/njs_unit_test.c | 3 +++ 6 files changed, 26 insertions(+), 11 deletions(-) diffs (105 lines): diff -r f8cc880d9b9b -r a3588250473b njs/njs_builtin.c --- a/njs/njs_builtin.c Tue Oct 11 17:44:01 2016 +0300 +++ b/njs/njs_builtin.c Tue Oct 11 17:44:05 2016 +0300 @@ -107,7 +107,8 @@ njs_builtin_objects_create(njs_vm_t *vm) }; static const njs_object_init_t *object_init[] = { - &njs_math_object_init, + NULL, /* global this */ + &njs_math_object_init, /* Math */ }; static const njs_object_init_t *function_init[] = { @@ -164,12 +165,14 @@ njs_builtin_objects_create(njs_vm_t *vm) objects = vm->shared->objects; - for (i = NJS_OBJECT_MATH; i < NJS_OBJECT_MAX; i++) { - ret = njs_object_hash_create(vm, &objects[i].shared_hash, - object_init[i]->properties, - object_init[i]->items); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; + for (i = NJS_OBJECT_THIS; i < NJS_OBJECT_MAX; i++) { + if (object_init[i] != NULL) { + ret = njs_object_hash_create(vm, &objects[i].shared_hash, + object_init[i]->properties, + object_init[i]->items); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } } objects[i].shared = 1; diff -r f8cc880d9b9b -r a3588250473b njs/njs_generator.c --- a/njs/njs_generator.c Tue Oct 11 17:44:01 2016 +0300 +++ b/njs/njs_generator.c Tue Oct 11 17:44:05 2016 +0300 @@ -289,6 +289,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_NAME: return njs_generate_name(vm, parser, node); + case NJS_TOKEN_GLOBAL_THIS: case NJS_TOKEN_MATH: case NJS_TOKEN_EVAL: case NJS_TOKEN_TO_STRING: diff -r f8cc880d9b9b -r a3588250473b njs/njs_parser.c --- a/njs/njs_parser.c Tue Oct 11 17:44:01 2016 +0300 +++ b/njs/njs_parser.c Tue Oct 11 17:44:05 2016 +0300 @@ -1644,8 +1644,14 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa case NJS_TOKEN_THIS: nxt_thread_log_debug("JS: this"); - node->index = NJS_INDEX_THIS; - break; + if (parser->scope != NJS_SCOPE_GLOBAL) { + node->index = NJS_INDEX_THIS; + break; + } + + node->token = NJS_TOKEN_GLOBAL_THIS; + + /* Fall through. */ case NJS_TOKEN_MATH: return njs_parser_builtin_object(vm, parser, node); diff -r f8cc880d9b9b -r a3588250473b njs/njs_parser.h --- a/njs/njs_parser.h Tue Oct 11 17:44:01 2016 +0300 +++ b/njs/njs_parser.h Tue Oct 11 17:44:05 2016 +0300 @@ -160,8 +160,9 @@ typedef enum { NJS_TOKEN_THIS, -#define NJS_TOKEN_FIRST_OBJECT NJS_TOKEN_MATH +#define NJS_TOKEN_FIRST_OBJECT NJS_TOKEN_GLOBAL_THIS + NJS_TOKEN_GLOBAL_THIS, NJS_TOKEN_MATH, NJS_TOKEN_OBJECT_CONSTRUCTOR, diff -r f8cc880d9b9b -r a3588250473b njs/njs_vm.h --- a/njs/njs_vm.h Tue Oct 11 17:44:01 2016 +0300 +++ b/njs/njs_vm.h Tue Oct 11 17:44:05 2016 +0300 @@ -741,7 +741,8 @@ enum njs_constructor_e { enum njs_object_e { - NJS_OBJECT_MATH = 0, + NJS_OBJECT_THIS = 0, + NJS_OBJECT_MATH, #define NJS_OBJECT_MAX (NJS_OBJECT_MATH + 1) }; diff -r f8cc880d9b9b -r a3588250473b njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 11 17:44:01 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 11 17:44:05 2016 +0300 @@ -4237,6 +4237,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("/./ instanceof Object"), nxt_string("true") }, + { nxt_string("this"), + nxt_string("[object Object]") }, + { nxt_string("var o = Object(); o"), nxt_string("[object Object]") }, From mdounin at mdounin.ru Tue Oct 11 15:02:17 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 11 Oct 2016 15:02:17 +0000 Subject: [nginx] Updated OpenSSL used for win32 builds. Message-ID: details: http://hg.nginx.org/nginx/rev/e78705391830 branches: changeset: 6738:e78705391830 user: Maxim Dounin date: Tue Oct 11 16:52:48 2016 +0300 description: Updated OpenSSL used for win32 builds. diffstat: misc/GNUmakefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -5,7 +5,7 @@ NGINX = nginx-$(VER) TEMP = tmp OBJS = objs.msvc8 -OPENSSL = openssl-1.0.2h +OPENSSL = openssl-1.0.2j ZLIB = zlib-1.2.8 PCRE = pcre-8.39 From mdounin at mdounin.ru Tue Oct 11 15:22:16 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 11 Oct 2016 15:22:16 +0000 Subject: [nginx] nginx-1.11.5-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/5253015a339a branches: changeset: 6739:5253015a339a user: Maxim Dounin date: Tue Oct 11 18:03:00 2016 +0300 description: nginx-1.11.5-RELEASE diffstat: docs/xml/nginx/changes.xml | 134 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 134 insertions(+), 0 deletions(-) diffs (144 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,140 @@ + + + + +???????? configure --with-ipv6 ?????????, +????????? IPv6 ?????? ?????????? ?????????????. + + +the --with-ipv6 configure option was removed, +now IPv6 support is configured automatically. + + + + + +??????, ???? ? ????? upstream ?? ????????? ????????? ????????, +nginx ?? ?????????? ?????????? ?????? ???? ????????, ??? ????? ?????, +? ??????? ????????? fail_timeout. + + +now if there are no available servers in an upstream, +nginx will not reset number of failures of all servers as it previously did, +but will wait for fail_timeout to expire. + + + + + +?????? ngx_stream_ssl_preread_module. + + +the ngx_stream_ssl_preread_module. + + + + + +????????? server ? ????? upstream ???????????? ???????? max_conns. + + +the "server" directive in the "upstream" context supports +the "max_conns" parameter. + + + + + +???????? configure --with-compat. + + +the --with-compat configure option. + + + + + +????????? manager_files, manager_threshold ? manager_sleep +???????? proxy_cache_path, fastcgi_cache_path, scgi_cache_path ? +uwsgi_cache_path. + + +"manager_files", "manager_threshold", and "manager_sleep" parameters +of the "proxy_cache_path", "fastcgi_cache_path", "scgi_cache_path", and +"uwsgi_cache_path" directives. + + + + + +??? ?????? perl-?????? ?? ?????????????? ?????, +???????? ? ??????? ????????? configure --with-ld-opt. + + +flags passed by the --with-ld-opt configure option +were not used while building perl module. + + + + + +? ????????? add_after_body ??? ????????????? ????????? ? ?????????? sub_filter. + + +in the "add_after_body" directive when used with the "sub_filter" directive. + + + + + +? ?????????? $realip_remote_addr. + + +in the $realip_remote_addr variable. + + + + + +????????? dav_access, proxy_store_access, fastcgi_store_access, +scgi_store_access ? uwsgi_store_access +???????????? ?????, ???????? ??? ????????????. + + +the "dav_access", "proxy_store_access", "fastcgi_store_access", +"scgi_store_access", and "uwsgi_store_access" directives +ignored permissions specified for user. + + + + + +unix domain listen-?????? ????? ?? ????????????? +??? ?????????? ???????????? ????? ?? Linux. + + +unix domain listen sockets might not be inherited +during binary upgrade on Linux. + + + + + +nginx ????????? ?????? 400 ?? ??????? +? ???????? "-" ? HTTP-??????. + + +nginx returned the 400 response on requests +with the "-" character in the HTTP method. + + + + + + From mdounin at mdounin.ru Tue Oct 11 15:22:20 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 11 Oct 2016 15:22:20 +0000 Subject: [nginx] release-1.11.5 tag Message-ID: details: http://hg.nginx.org/nginx/rev/7cdf69d012f0 branches: changeset: 6740:7cdf69d012f0 user: Maxim Dounin date: Tue Oct 11 18:03:01 2016 +0300 description: release-1.11.5 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -403,3 +403,4 @@ cb783d9cc19761e14e1285d91c38f4b84d0b8756 4d3b3a13a8cf5fc3351a7f167d1c13325e00f21c release-1.11.2 b83a067949a3384a49fd3d943eb8d0997b31f87b release-1.11.3 953512ca02c6f63b4fcbbc3e10d0d9835896bf99 release-1.11.4 +5253015a339aaca0a3111473d3e931b6d4752393 release-1.11.5 From igor at sysoev.ru Tue Oct 11 17:15:42 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 11 Oct 2016 17:15:42 +0000 Subject: [njs] Constructor function prototypes should be real functions. Message-ID: details: http://hg.nginx.org/njs/rev/beba11b9f2a1 branches: changeset: 197:beba11b9f2a1 user: Igor Sysoev date: Tue Oct 11 20:09:18 2016 +0300 description: Constructor function prototypes should be real functions. diffstat: njs/njs_builtin.c | 16 +++++++++++++++- njs/njs_vm.h | 2 +- njs/test/njs_unit_test.c | 3 +++ 3 files changed, 19 insertions(+), 2 deletions(-) diffs (63 lines): diff -r a3588250473b -r beba11b9f2a1 njs/njs_builtin.c --- a/njs/njs_builtin.c Tue Oct 11 17:44:05 2016 +0300 +++ b/njs/njs_builtin.c Tue Oct 11 20:09:18 2016 +0300 @@ -34,6 +34,16 @@ typedef struct { } njs_function_init_t; +static njs_ret_t +njs_prototype_function(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + vm->retval = njs_value_void; + + return NXT_OK; +} + + nxt_int_t njs_builtin_objects_create(njs_vm_t *vm) { @@ -75,7 +85,11 @@ njs_builtin_objects_create(njs_vm_t *vm) { .object_value = { .value = njs_string(""), .object = { .type = NJS_OBJECT_STRING } } }, - { .object = { .type = NJS_FUNCTION } }, + { .function = { .native = 1, + .args_offset = 1, + .u.native = njs_prototype_function, + .object = { .type = NJS_FUNCTION } } }, + { .object = { .type = NJS_REGEXP } }, { .date = { .time = NJS_NAN, diff -r a3588250473b -r beba11b9f2a1 njs/njs_vm.h --- a/njs/njs_vm.h Tue Oct 11 17:44:05 2016 +0300 +++ b/njs/njs_vm.h Tue Oct 11 20:09:18 2016 +0300 @@ -321,12 +321,12 @@ typedef union { .type = NJS_FUNCTION, \ .truth = 1, \ .u.function = & (njs_function_t) { \ - .object.shared = 1, \ .native = 1, \ .continuation_size = _size, \ .args_types = { __VA_ARGS__ }, \ .args_offset = 1, \ .u.native = _function, \ + .object = { .type = NJS_FUNCTION, .shared = 1 }, \ } \ } \ } diff -r a3588250473b -r beba11b9f2a1 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 11 17:44:05 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 11 20:09:18 2016 +0300 @@ -4288,6 +4288,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("({}).constructor === Object"), nxt_string("true") }, + { nxt_string("var a = Object.__proto__; a()"), + nxt_string("undefined") }, + { nxt_string("var a = Array(3); a"), nxt_string(",,") }, From bjornar.ness at gmail.com Tue Oct 11 18:26:29 2016 From: bjornar.ness at gmail.com (=?UTF-8?Q?Bj=C3=B8rnar_Ness?=) Date: Tue, 11 Oct 2016 20:26:29 +0200 Subject: slice module and upstream sent more data than specified in "Content-Length" Message-ID: Hello nginx-devel I am seeing lots of 'upstream sent more data than specified in "Content-Length"' errors when using nginx with proxy_cache and slice module. The relevant nginx.conf settings are: > slice 1m; > proxy_cache_lock on; > proxy_cache_key $uri$is_args$args$slice_range; > proxy_set_header Range $slice_range; > proxy_set_header Connection ""; I have tried debugging this with tcpdump and curl, and I dont see that upstream (also nginx) is not true to content-length header. I have also tried playing aroung with buffering, but no success. Has anyone else experienced similar issues? -- Bj(/)rnar From george at ucdn.com Wed Oct 12 10:22:08 2016 From: george at ucdn.com (George .) Date: Wed, 12 Oct 2016 13:22:08 +0300 Subject: freeing buffers after sending them Message-ID: Hi all, What do you think about freeing buffers after being sent by send_chain? Because we have a special case were we use 4 megabyte buffer instead of nginx default 8 * 8 K and we found that these buffers are actually freed after request had been finished, so if there hundreds of slow downstream connection nginx will eat a lot of RAM. I'm just curious if I explicitly return already consumed buffer with ngx_pfree will affect something (our bunch of tests shows at least there is not crash or unexpected behaviour) @@ -284,6 +284,13 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) chain = c->send_chain(c, r->out, limit); + /* free buffs that are already sent */ + for (cl = r->out; cl; /* void */) { + ln = cl; + cl = cl->next; + ngx_pfree(c->pool, ln->buf); + } + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http write filter %p", chain) -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Wed Oct 12 11:30:48 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 12 Oct 2016 14:30:48 +0300 Subject: freeing buffers after sending them In-Reply-To: References: Message-ID: <1636416.LD5AQ8Ch76@vbart-workstation> On Wednesday 12 October 2016 13:22:08 George . wrote: > Hi all, > > What do you think about freeing buffers after being sent by send_chain? > Because we have a special case were we use 4 megabyte buffer instead of > nginx default 8 * 8 K and we found that these buffers are actually freed > after request had been finished, so if there hundreds of slow downstream > connection nginx will eat a lot of RAM. > > I'm just curious if I explicitly return already consumed buffer with > ngx_pfree will affect something (our bunch of tests shows at least there > is not crash or unexpected behaviour) > Buffers are not allocated from "c->pool", so the code below does nothing except wasting CPU. And this is the only reason, why the patch doesn't break everything. wbr, Valentin V. Bartenev > > @@ -284,6 +284,13 @@ ngx_http_write_filter(ngx_http_request_t *r, > ngx_chain_t *in) > > chain = c->send_chain(c, r->out, limit); > > + /* free buffs that are already sent */ > + for (cl = r->out; cl; /* void */) { > + ln = cl; > + cl = cl->next; > + ngx_pfree(c->pool, ln->buf); > + } > + > ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, > "http write filter %p", chain) From thierry.magnien at sfr.com Wed Oct 12 11:49:13 2016 From: thierry.magnien at sfr.com (MAGNIEN, Thierry) Date: Wed, 12 Oct 2016 11:49:13 +0000 Subject: slice module and upstream sent more data than specified in "Content-Length" In-Reply-To: References: Message-ID: <5D103CE839D50E4CBC62C9FD7B83287C01F14D94A8@EXCN015.encara.local.ads> Hi, Is your origin server something like Apache + mod_fastcgi + mod_deflate ? I did not see this specifically with Nginx but you may hit the same issue described here: https://ma.ttias.be/apaches-mod_fastcgi-mod_deflate-troubles/ Best regards, Thierry -----Message d'origine----- De?: nginx-devel [mailto:nginx-devel-bounces at nginx.org] De la part de Bj?rnar Ness Envoy??: mardi 11 octobre 2016 20:26 ??: nginx-devel at nginx.org Objet?: slice module and upstream sent more data than specified in "Content-Length" Hello nginx-devel I am seeing lots of 'upstream sent more data than specified in "Content-Length"' errors when using nginx with proxy_cache and slice module. The relevant nginx.conf settings are: > slice 1m; > proxy_cache_lock on; > proxy_cache_key $uri$is_args$args$slice_range; > proxy_set_header Range $slice_range; > proxy_set_header Connection ""; I have tried debugging this with tcpdump and curl, and I dont see that upstream (also nginx) is not true to content-length header. I have also tried playing aroung with buffering, but no success. Has anyone else experienced similar issues? -- Bj(/)rnar _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From george at ucdn.com Wed Oct 12 12:05:48 2016 From: george at ucdn.com (George .) Date: Wed, 12 Oct 2016 15:05:48 +0300 Subject: freeing buffers after sending them In-Reply-To: <1636416.LD5AQ8Ch76@vbart-workstation> References: <1636416.LD5AQ8Ch76@vbart-workstation> Message-ID: Hi Valentin, Than you for your fast and correct reply. Yes, you are right, it was oversight that r->out->buf if taken from pipe->pool, which is actually r->pool. What if we pfree this bufs from r->pool? Who holds the reference after sending these buffers (except may be in NGX_THREADS version)? On Wed, Oct 12, 2016 at 2:30 PM, Valentin V. Bartenev wrote: > On Wednesday 12 October 2016 13:22:08 George . wrote: > > Hi all, > > > > What do you think about freeing buffers after being sent by send_chain? > > Because we have a special case were we use 4 megabyte buffer instead of > > nginx default 8 * 8 K and we found that these buffers are actually freed > > after request had been finished, so if there hundreds of slow downstream > > connection nginx will eat a lot of RAM. > > > > I'm just curious if I explicitly return already consumed buffer with > > ngx_pfree will affect something (our bunch of tests shows at least there > > is not crash or unexpected behaviour) > > > > > Buffers are not allocated from "c->pool", so > the code below does nothing except wasting CPU. > > And this is the only reason, why the patch doesn't > break everything. > > wbr, Valentin V. Bartenev > > > > > > > @@ -284,6 +284,13 @@ ngx_http_write_filter(ngx_http_request_t *r, > > ngx_chain_t *in) > > > > chain = c->send_chain(c, r->out, limit); > > > > + /* free buffs that are already sent */ > > + for (cl = r->out; cl; /* void */) { > > + ln = cl; > > + cl = cl->next; > > + ngx_pfree(c->pool, ln->buf); > > + } > > + > > ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, > > "http write filter %p", chain) > > _______________________________________________ > 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 arut at nginx.com Wed Oct 12 12:09:57 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Wed, 12 Oct 2016 15:09:57 +0300 Subject: slice module and upstream sent more data than specified in "Content-Length" In-Reply-To: References: Message-ID: <20161012120957.GA52217@Romans-MacBook-Air.local> Hi, On Tue, Oct 11, 2016 at 08:26:29PM +0200, Bj?rnar Ness wrote: > Hello nginx-devel > > I am seeing lots of 'upstream sent more data than specified in > "Content-Length"' errors > when using nginx with proxy_cache and slice module. The relevant > nginx.conf settings are: > > > > slice 1m; > > proxy_cache_lock on; > > proxy_cache_key $uri$is_args$args$slice_range; > > proxy_set_header Range $slice_range; > > proxy_set_header Connection ""; > > I have tried debugging this with tcpdump and curl, and I dont see that > upstream (also nginx) is > not true to content-length header. > > I have also tried playing aroung with buffering, but no success. Has > anyone else experienced > similar issues? Do you have this issue without slice? Anyway, it would be nice to see debug log http://nginx.org/en/docs/debugging_log.html -- Roman Arutyunyan From llz at antiy.cn Wed Oct 12 12:44:25 2016 From: llz at antiy.cn (=?UTF-8?B?5p2O5p6X5ZOy?=) Date: Wed, 12 Oct 2016 20:44:25 +0800 Subject: [patch]fork: subprocess quit when parent died Message-ID: <59975b03-3f23-4443-a993-07d83c7f6257.llz@antiy.cn> # HG changeset patch # User lilinzhe # Date 1476275566 -28800 # Node ID 07d294d39cc6ec07769c1a72d5ee9b7da27b9ce1 # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 fork: subprocess quit when parent died diff -r 7cdf69d012f0 -r 07d294d39cc6 auto/os/linux --- a/auto/os/linux Tue Oct 11 18:03:01 2016 +0300 +++ b/auto/os/linux Wed Oct 12 20:32:46 2016 +0800 @@ -157,6 +157,18 @@ . auto/feature +# prctl(PR_SET_PDEATHSIG) + +ngx_feature="prctl(PR_SET_PDEATHSIG)" +ngx_feature_name="NGX_HAVE_PR_SET_PDEATHSIG" +ngx_feature_run=yes +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) == -1) return 1" +. auto/feature + # sched_setaffinity() ngx_feature="sched_setaffinity()" diff -r 7cdf69d012f0 -r 07d294d39cc6 src/os/unix/ngx_daemon.c --- a/src/os/unix/ngx_daemon.c Tue Oct 11 18:03:01 2016 +0300 +++ b/src/os/unix/ngx_daemon.c Wed Oct 12 20:32:46 2016 +0800 @@ -26,6 +26,13 @@ exit(0); } + #if(NGX_HAVE_PR_SET_PDEATHSIG) + if(prctl(PR_SET_PDEATHSIG, SIGTERM, 0,0,0) == -1){ + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "prctl PR_SET_PDEATHSIG failed"); + return NGX_ERROR; + } + #endif + ngx_pid = ngx_getpid(); if (setsid() == -1) { diff -r 7cdf69d012f0 -r 07d294d39cc6 src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c Tue Oct 11 18:03:01 2016 +0300 +++ b/src/os/unix/ngx_process.c Wed Oct 12 20:32:46 2016 +0800 @@ -195,6 +195,13 @@ case 0: ngx_pid = ngx_getpid(); + + #if(NGX_HAVE_PR_SET_PDEATHSIG) + if(prctl(PR_SET_PDEATHSIG, SIGTERM, 0,0,0) == -1){ + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "prctl PR_SET_PDEATHSIG failed"); + return NGX_ERROR; + } + #endif proc(cycle, data); break; From vbart at nginx.com Wed Oct 12 12:58:46 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 12 Oct 2016 15:58:46 +0300 Subject: freeing buffers after sending them In-Reply-To: References: <1636416.LD5AQ8Ch76@vbart-workstation> Message-ID: <2692401.NkvVIACjtm@vbart-workstation> On Wednesday 12 October 2016 15:05:48 George . wrote: > Hi Valentin, > > Than you for your fast and correct reply. > > Yes, you are right, it was oversight that r->out->buf if taken from > pipe->pool, which is actually r->pool. > What if we pfree this bufs from r->pool? Who holds the reference after > sending these buffers (except may be in NGX_THREADS version)? > [..] These buffers are reused for continuing sending response. wbr, Valentin V. Bartenev From bjornar.ness at gmail.com Wed Oct 12 13:49:04 2016 From: bjornar.ness at gmail.com (=?UTF-8?Q?Bj=C3=B8rnar_Ness?=) Date: Wed, 12 Oct 2016 15:49:04 +0200 Subject: slice module and upstream sent more data than specified in "Content-Length" In-Reply-To: <20161012120957.GA52217@Romans-MacBook-Air.local> References: <20161012120957.GA52217@Romans-MacBook-Air.local> Message-ID: 2016-10-12 14:09 GMT+02:00 Roman Arutyunyan : > Do you have this issue without slice? No, if I send a the same request that slice module would send to upstream through nginx without slice activated, I do not see the same errors > Anyway, it would be nice to see debug log Working on it.. -- Bj(/)rnar From whissi at gentoo.org Wed Oct 12 13:58:25 2016 From: whissi at gentoo.org (Thomas Deutschmann) Date: Wed, 12 Oct 2016 15:58:25 +0200 Subject: When to use --with-compat configure option? Message-ID: <6f944f26-52c0-f856-4b3b-331f191962f0@gentoo.org> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Hi, nginx-1.11.5 introduced a new configure option "--with-compat" however I don't find any documentation regarding this option. Could you please give us some insight when you expect that this option should be used (especially from distribution view, i.e. package maintainer)? Thanks! - -- Regards, Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0 iQJ8BAEBCgBmBQJX/kF+XxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25zLm9w ZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQzM0M1ODQ4MkM0MDIyOTJEMkUzQzVDMDY5 NzA5RjkwQzNDOTZGRkM4AAoJEJcJ+Qw8lv/INBcQAIhUm8UrMCcXiKQiT+zpMUkz 5IkYehNd23b/zJMY5vNu6nt9sqA5QiYX63p02nnaebJG2rCjRteXYtvqemzKEGfE Lz8pdcQKv5Nn3ZyaDR8Z6vQ8pjP3seOXQYnfwu26j4SMx29p6Miu/9ARwbHTi5sa U36qPv/a3y1f7rMeO49XTEOCGJrRK17AKRODuRLwHU9azDWY+b6vyq42aLEwMxh5 RJLAMH5ts2oc1PA9mjkhCna2jbbdMYEH2AgSSyjcUuCgOjIPiddEUEa90AXWaGIE TjnouKrglHXhow/qVGvKfClLBxX1jOUb/m7wkr/2yFLr7pVP2ys4VEJY9hkZwaDz 5DkaGILvnT9yZt75+Au0PL6Fq2qoe4CnnmqXtMpOcxi49Yvx3rXOcX7QoeQN+L8b aHuDYaYIVeFZ7eTPP5J6axbWFdRC6z4fKQNTYNR3vqSqFYm2KZJNaj0QuZzY1aEy XYMXEVVp4u5BNTzL6J8sgJdbwJM9sOyYA1zcpP6lyWP+Q8BVjliiFkTJivefUmhz XYdX0h7nQfIMxdSCKQByPKZ6BAd161yPkGhGkzVRmPhtJtTI9p60KAp9jlKIUriq matldl6qcnFwv1Xv0lDjgzpwaVxes1S8elPnkTT6IFTyrWvpA1CE8/V+iMqJQPht mrpqrsuqZ+uUKPAj9dqe =3bTj -----END PGP SIGNATURE----- From mdounin at mdounin.ru Wed Oct 12 14:22:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 12 Oct 2016 17:22:27 +0300 Subject: [patch]fork: subprocess quit when parent died In-Reply-To: <59975b03-3f23-4443-a993-07d83c7f6257.llz@antiy.cn> References: <59975b03-3f23-4443-a993-07d83c7f6257.llz@antiy.cn> Message-ID: <20161012142227.GI73038@mdounin.ru> Hello! On Wed, Oct 12, 2016 at 08:44:25PM +0800, ??? wrote: > # HG changeset patch > # User lilinzhe > # Date 1476275566 -28800 > # Node ID 07d294d39cc6ec07769c1a72d5ee9b7da27b9ce1 > # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 > fork: subprocess quit when parent died > > diff -r 7cdf69d012f0 -r 07d294d39cc6 auto/os/linux > --- a/auto/os/linux Tue Oct 11 18:03:01 2016 +0300 > +++ b/auto/os/linux Wed Oct 12 20:32:46 2016 +0800 > @@ -157,6 +157,18 @@ > . auto/feature > > > +# prctl(PR_SET_PDEATHSIG) > + > +ngx_feature="prctl(PR_SET_PDEATHSIG)" > +ngx_feature_name="NGX_HAVE_PR_SET_PDEATHSIG" > +ngx_feature_run=yes > +ngx_feature_incs="#include > + #include " > +ngx_feature_path= > +ngx_feature_libs= > +ngx_feature_test="if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) == -1) return 1" > +. auto/feature > + > # sched_setaffinity() > > ngx_feature="sched_setaffinity()" > diff -r 7cdf69d012f0 -r 07d294d39cc6 src/os/unix/ngx_daemon.c > --- a/src/os/unix/ngx_daemon.c Tue Oct 11 18:03:01 2016 +0300 > +++ b/src/os/unix/ngx_daemon.c Wed Oct 12 20:32:46 2016 +0800 > @@ -26,6 +26,13 @@ > exit(0); > } > > + #if(NGX_HAVE_PR_SET_PDEATHSIG) > + if(prctl(PR_SET_PDEATHSIG, SIGTERM, 0,0,0) == -1){ > + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "prctl PR_SET_PDEATHSIG failed"); > + return NGX_ERROR; > + } > + #endif > + > ngx_pid = ngx_getpid(); > > if (setsid() == -1) { > diff -r 7cdf69d012f0 -r 07d294d39cc6 src/os/unix/ngx_process.c > --- a/src/os/unix/ngx_process.c Tue Oct 11 18:03:01 2016 +0300 > +++ b/src/os/unix/ngx_process.c Wed Oct 12 20:32:46 2016 +0800 > @@ -195,6 +195,13 @@ > > case 0: > ngx_pid = ngx_getpid(); > + > + #if(NGX_HAVE_PR_SET_PDEATHSIG) > + if(prctl(PR_SET_PDEATHSIG, SIGTERM, 0,0,0) == -1){ > + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "prctl PR_SET_PDEATHSIG failed"); > + return NGX_ERROR; > + } > + #endif > proc(cycle, data); > break; It is not clear what problem you are trying to solve. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Oct 12 14:33:59 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 12 Oct 2016 17:33:59 +0300 Subject: When to use --with-compat configure option? In-Reply-To: <6f944f26-52c0-f856-4b3b-331f191962f0@gentoo.org> References: <6f944f26-52c0-f856-4b3b-331f191962f0@gentoo.org> Message-ID: <20161012143359.GJ73038@mdounin.ru> Hello! On Wed, Oct 12, 2016 at 03:58:25PM +0200, Thomas Deutschmann wrote: > nginx-1.11.5 introduced a new configure option "--with-compat" however > I don't find any documentation regarding this option. > > Could you please give us some insight when you expect that this option > should be used (especially from distribution view, i.e. package > maintainer)? The only documentation currently available is: $ ./configure --help | grep compat --with-compat dynamic modules compatibility Expanding the above, this option enables dynamic modules compatibility, that is, it ensures that appropriate fields in structures are present (or appropriately-sized placeholders are added). This makes it possible to compile additional dynamic modules with minimal efforts assuming main nginx binary is compiled --with-compat. Just $ ./configure --with-compat --add-dynamic-module=/path/to/module should be enough to compile a binary compatible module (assuming the same platform is used for compilation). >From package maintaining point of view it should be a good idea to add the option to nginx builds. This will allow others to easily compile dynamic modules to be loaded into nginx shipped in the package. -- Maxim Dounin http://nginx.org/ From francois.berenger at inria.fr Wed Oct 12 15:53:17 2016 From: francois.berenger at inria.fr (Francois BERENGER) Date: Wed, 12 Oct 2016 17:53:17 +0200 Subject: question about how to use the ngx_radix_tree Message-ID: <6a24d3ec-7f63-2916-9034-758380957e5e@inria.fr> Dear list, I am interested in using this data structure. Would it be possible to have a few usage examples of it? I looked in the nginx code via github but found only few usages and not very informative about how to use it properly. I am interested in those functions: ngx_radix_tree_t *ngx_radix_tree_create(ngx_int_t preallocate); ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask, uintptr_t value); ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask); uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key); Especially, in insert and delete I don't know what should be the value of the mask parameter. Should I compute this mask? How? Thanks a lot, Francois. From igor at sysoev.ru Wed Oct 12 16:30:48 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 12 Oct 2016 16:30:48 +0000 Subject: [njs] A fix in Array.slice() function. Message-ID: details: http://hg.nginx.org/njs/rev/8046b999aaaf branches: changeset: 198:8046b999aaaf user: Igor Sysoev date: Wed Oct 12 19:08:57 2016 +0300 description: A fix in Array.slice() function. diffstat: njs/njs_array.c | 34 +++++++++++++++++++++------------- njs/test/njs_unit_test.c | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+), 13 deletions(-) diffs (74 lines): diff -r beba11b9f2a1 -r 8046b999aaaf njs/njs_array.c --- a/njs/njs_array.c Tue Oct 11 20:09:18 2016 +0300 +++ b/njs/njs_array.c Wed Oct 12 19:08:57 2016 +0300 @@ -387,21 +387,29 @@ njs_array_prototype_slice(njs_vm_t *vm, } } - end = length; - - if (nargs > 2) { - end = args[2].data.u.number; - - if (end < 0) { - end += length; - } - } - - length = end - start; - - if (length < 0) { + if (start >= length) { start = 0; length = 0; + + } else { + end = length; + + if (nargs > 2) { + end = args[2].data.u.number; + + if (end < 0) { + end += length; + } + } + + if (length >= end) { + length = end - start; + + if (length < 0) { + start = 0; + length = 0; + } + } } } } diff -r beba11b9f2a1 -r 8046b999aaaf njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 11 20:09:18 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Oct 12 19:08:57 2016 +0300 @@ -2260,6 +2260,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("a = [1,2]; a[100] = 100; a[100] +' '+ a.length"), nxt_string("100 101") }, + { nxt_string("Array.prototype.slice(1)"), + nxt_string("") }, + + { nxt_string("Array.prototype.slice(1,2)"), + nxt_string("") }, + + { nxt_string("Array.prototype.pop()"), + nxt_string("undefined") }, + + { nxt_string("Array.prototype.shift()"), + nxt_string("undefined") }, + + { nxt_string("[0,1,2,3,4].slice(1,4)"), + nxt_string("1,2,3") }, + + { nxt_string("[0,1,2,3,4].slice(6,7)"), + nxt_string("") }, + { nxt_string("a = [1,2,3,4,5]; b = a.slice(3); b[0] +' '+ b[1] +' '+ b[2]"), nxt_string("4 5 undefined") }, From whissi at gentoo.org Wed Oct 12 22:02:43 2016 From: whissi at gentoo.org (Thomas Deutschmann) Date: Thu, 13 Oct 2016 00:02:43 +0200 Subject: When to use --with-compat configure option? In-Reply-To: <20161012143359.GJ73038@mdounin.ru> References: <6f944f26-52c0-f856-4b3b-331f191962f0@gentoo.org> <20161012143359.GJ73038@mdounin.ru> Message-ID: <05cab693-e399-2a7c-25e0-f4ad9e6f1751@gentoo.org> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On 2016-10-12 16:33, Maxim Dounin wrote: > [...] > > From package maintaining point of view it should be a good idea to > add the option to nginx builds. This will allow others to easily > compile dynamic modules to be loaded into nginx shipped in the > package. Thanks! - -- Regards, Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0 iQJ8BAEBCgBmBQJX/rL7XxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25zLm9w ZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQzM0M1ODQ4MkM0MDIyOTJEMkUzQzVDMDY5 NzA5RjkwQzNDOTZGRkM4AAoJEJcJ+Qw8lv/IzJAP/iEKopbEs0jrc2N91LK8/ydm IbedP7cK41RwC/nrlWRUXtDIqS7C4edMHiTHgpLaZHdeaS4owAubWGcWCs1ShtRR yV4+oHWS3jkr08r4oYNYYgj9yMbApG5fhyJLhe5A7XszB87qiKlTnJHr5U89r2WY t9aywoUbR6lpsPfuTFUjBhh9EtxzlXw28tJztKtE1Pc9FRUhAV4F/A2LYMIQsKbx ve9n1CtG4EbNMDX0KlJ0KhDj3AdKGJpNX1Sdwb/8ub7Dd1ClUmzOedoFDZqdzZ2Q +GiepYe4WZ2G5Hgwao16tV37ccfuy1k/aqJFCpGIGAx3+dz31wMID2rEG3cWztkn VW8v54yh/PcBFdKRys4nV7BGwNtd9qgNDn3AAFUnGOzqRuThpAxfTB62OVcC1tG8 X0Y/nQme3EE9wbDCb3NjBkAkus4nPPgEVKH6dC1yB/HLk8Xh4ZCbirUDEaXLMfQD kWAaSwKMaX/WjZtZHeYV2jEH4/QiEyMbZRfXWs3X5XRFnjXatFn5/qRIqSNiUjkR jFEil6yxcqZxcxucN1NkkOpZzSC7pA1bDHaddNeC/4onDKpibTc3zqqnqkOY2W1g hEqc1UXyzUEpb1R9f6WzqOm++WK3+vYSVAxtnneNwvkUh4iTRQMavC+4dmeuA4Up TNrQB0s9Y3pQaXEUiarn =4gNx -----END PGP SIGNATURE----- From llz at antiy.cn Thu Oct 13 00:38:56 2016 From: llz at antiy.cn (=?UTF-8?B?5p2O5p6X5ZOy?=) Date: Thu, 13 Oct 2016 08:38:56 +0800 Subject: =?UTF-8?Q?path_purpose//Re=EF=BC=9A=5Bpatch=5Dfork=3A_subprocess_quit_when?= =?UTF-8?Q?_parent_died?= Message-ID: Thanks for reply. This patch is solving the problem that the sub process (worker process) will not quit when master process quits on SIGKILL. which will be done by OS (especially Linux) when system meet OOM. I've found a bug, and will send a new patch for comment. ------------------------------------------------------------------ ????Maxim Dounin ?????2016?10?12?(???) 22:22 ????nginx-devel ; ??? ????Re: [patch]fork: subprocess quit when parent died Hello! On Wed, Oct 12, 2016 at 08:44:25PM +0800, ??? wrote: > # HG changeset patch > # User lilinzhe > # Date 1476275566 -28800 > # Node ID 07d294d39cc6ec07769c1a72d5ee9b7da27b9ce1 > # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 > fork: subprocess quit when parent died > > diff -r 7cdf69d012f0 -r 07d294d39cc6 auto/os/linux > --- a/auto/os/linux Tue Oct 11 18:03:01 2016 +0300 > +++ b/auto/os/linux Wed Oct 12 20:32:46 2016 +0800 > @@ -157,6 +157,18 @@ > . auto/feature > > > +# prctl(PR_SET_PDEATHSIG) > + > +ngx_feature="prctl(PR_SET_PDEATHSIG)" > +ngx_feature_name="NGX_HAVE_PR_SET_PDEATHSIG" > +ngx_feature_run=yes > +ngx_feature_incs="#include > + #include " > +ngx_feature_path= > +ngx_feature_libs= > +ngx_feature_test="if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) == -1) return 1" > +. auto/feature > + > # sched_setaffinity() > > ngx_feature="sched_setaffinity()" > diff -r 7cdf69d012f0 -r 07d294d39cc6 src/os/unix/ngx_daemon.c > --- a/src/os/unix/ngx_daemon.c Tue Oct 11 18:03:01 2016 +0300 > +++ b/src/os/unix/ngx_daemon.c Wed Oct 12 20:32:46 2016 +0800 > @@ -26,6 +26,13 @@ > exit(0); > } > > + #if(NGX_HAVE_PR_SET_PDEATHSIG) > + if(prctl(PR_SET_PDEATHSIG, SIGTERM, 0,0,0) == -1){ > + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "prctl PR_SET_PDEATHSIG failed"); > + return NGX_ERROR; > + } > + #endif > + > ngx_pid = ngx_getpid(); > > if (setsid() == -1) { > diff -r 7cdf69d012f0 -r 07d294d39cc6 src/os/unix/ngx_process.c > --- a/src/os/unix/ngx_process.c Tue Oct 11 18:03:01 2016 +0300 > +++ b/src/os/unix/ngx_process.c Wed Oct 12 20:32:46 2016 +0800 > @@ -195,6 +195,13 @@ > > case 0: > ngx_pid = ngx_getpid(); > + > + #if(NGX_HAVE_PR_SET_PDEATHSIG) > + if(prctl(PR_SET_PDEATHSIG, SIGTERM, 0,0,0) == -1){ > + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "prctl PR_SET_PDEATHSIG failed"); > + return NGX_ERROR; > + } > + #endif > proc(cycle, data); > break; It is not clear what problem you are trying to solve. -- Maxim Dounin http://nginx.org/ From llz at antiy.cn Thu Oct 13 01:23:09 2016 From: llz at antiy.cn (=?UTF-8?B?5p2O5p6X5ZOy?=) Date: Thu, 13 Oct 2016 09:23:09 +0800 Subject: [patch]worker process: make sure to quit when master quits Message-ID: <038e9f13-a5b3-456b-b460-0eeb4135f7df.llz@antiy.cn> # HG changeset patch # User lilinzhe # Date 1476321680 -28800 # Node ID d13daa14b1df9e04d7bf339c1669740edf19de0e # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 worker process: make sure to quit when master quits when theres prctl(PR_SET_PDEATHSIG). make worker to use it. on linux system OOM, it might send SIGKILL to master, and make master quits. some daemon program might try to restart nginx. but when worker exists. the restart will fail for port in use problem. this commit fixs this problem. diff -r 7cdf69d012f0 -r d13daa14b1df auto/os/linux --- a/auto/os/linux Tue Oct 11 18:03:01 2016 +0300 +++ b/auto/os/linux Thu Oct 13 09:21:20 2016 +0800 @@ -157,6 +157,18 @@ . auto/feature +# prctl(PR_SET_PDEATHSIG) + +ngx_feature="prctl(PR_SET_PDEATHSIG)" +ngx_feature_name="NGX_HAVE_PR_SET_PDEATHSIG" +ngx_feature_run=yes +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) == -1) return 1" +. auto/feature + # sched_setaffinity() ngx_feature="sched_setaffinity()" diff -r 7cdf69d012f0 -r d13daa14b1df src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c Tue Oct 11 18:03:01 2016 +0300 +++ b/src/os/unix/ngx_process_cycle.c Thu Oct 13 09:21:20 2016 +0800 @@ -869,6 +869,15 @@ #endif +#if(NGX_HAVE_PR_SET_PDEATHSIG) + /* + * when system OOM and send SIGKILL to master. make slave receive SIGTERM to quit. + */ + if(prctl(PR_SET_PDEATHSIG, SIGTERM) == -1){ + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "prctl PR_SET_PDEATHSIG failed"); + } +#endif + if (ccf->working_directory.len) { if (chdir((char *) ccf->working_directory.data) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, From mdounin at mdounin.ru Thu Oct 13 03:04:11 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 13 Oct 2016 06:04:11 +0300 Subject: =?UTF-8?Q?Re=3A_path_purpose//Re=EF=BC=9A=5Bpatch=5Dfork=3A_subprocess_qui?= =?UTF-8?Q?t_when_parent_died?= In-Reply-To: References: Message-ID: <20161013030410.GO73038@mdounin.ru> Hello! On Thu, Oct 13, 2016 at 08:38:56AM +0800, ??? wrote: > This patch is solving the problem that the sub process (worker > process) will not quit when master process quits on SIGKILL. > which will be done by OS (especially Linux) when system meet > OOM. Why do you think that worker processes should exit when master process is killed by OOM? I would rather say they shouldn't and should continue to work as long as they can. -- Maxim Dounin http://nginx.org/ From hongzhidao at gmail.com Thu Oct 13 04:10:21 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Thu, 13 Oct 2016 12:10:21 +0800 Subject: =?UTF-8?Q?Re=3A_path_purpose//Re=EF=BC=9A=5Bpatch=5Dfork=3A_subprocess_qui?= =?UTF-8?Q?t_when_parent_died?= In-Reply-To: <20161013030410.GO73038@mdounin.ru> References: <20161013030410.GO73038@mdounin.ru> Message-ID: Hello! It's a common case that all the worker processes are still live while the master process isn't exist. So I think nginx should continue to work as Maxim said. Btw, we noticed that nginx.pid is deleted when we do the upgrade command. kill -USR2 nginx.pid; sleep(2); kill -HUP nginx.oldpid; What reason? Thanks. B.R~ 2016-10-13 11:04 GMT+08:00 Maxim Dounin : > Hello! > > On Thu, Oct 13, 2016 at 08:38:56AM +0800, ??? wrote: > > > This patch is solving the problem that the sub process (worker > > process) will not quit when master process quits on SIGKILL. > > which will be done by OS (especially Linux) when system meet > > OOM. > > Why do you think that worker processes should exit when master > process is killed by OOM? I would rather say they shouldn't and > should continue to work as long as they can. > > -- > 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 llz at antiy.cn Thu Oct 13 05:46:28 2016 From: llz at antiy.cn (=?UTF-8?B?5p2O5p6X5ZOy?=) Date: Thu, 13 Oct 2016 13:46:28 +0800 Subject: =?UTF-8?Q?patch_purpose//Re=EF=BC=9A=5Bpatch=5Dfork=3A_subprocess_quit_whe?= =?UTF-8?Q?n_parent_died?= Message-ID: <9cf63f5f-f639-4e91-a6f3-e045dde08667.llz@antiy.cn> Hi, Maxim.?When master OOM, system daemon program like supervisord will trying to pull it up. but it can?t be done because of worker binds the port.?And i believe the master process shell handler all the resources. Slaves shell not exist on its own.?? -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Oct 13 05:50:29 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 13 Oct 2016 08:50:29 +0300 Subject: [PATCH] Mail: Support SASL EXTERNAL (RFC 4422) In-Reply-To: <205f2148260460379f9b.1475911862@lena> References: <205f2148260460379f9b.1475911862@lena> Message-ID: <20161013055029.GP73038@mdounin.ru> Hello! On Sat, Oct 08, 2016 at 06:31:02PM +1100, Rob N ? wrote: > # HG changeset patch > # User Rob N ? > # Date 1475910300 -39600 > # Sat Oct 08 18:05:00 2016 +1100 > # Node ID 205f2148260460379f9b0889cdb8015994028c73 > # Parent 1606a817c1d48ed351f1dd7d9cb9c996e2c77b9a > Mail: Support SASL EXTERNAL (RFC 4422) > > This is needed to allow TLS client certificate auth to work. With > ssl_verify_client configured, the auth daemon can choose to allow the > connection to proceed based on the certificate data. > > This has been tested with Thunderbird for IMAP only. I've not yet found a > client that will do client certificate auth for POP3 or SMTP, and the method is > not really documented anywhere that I can find. That said, its simple enough > that the way I've done is probably right. Thank you for the patch. Overral it looks good, though there are some things I would like to do differently in the pop3 module. See below. [...] > diff -r 1606a817c1d4 -r 205f21482604 src/mail/ngx_mail_pop3_module.c > --- a/src/mail/ngx_mail_pop3_module.c Fri Oct 07 16:59:14 2016 +0300 > +++ b/src/mail/ngx_mail_pop3_module.c Sat Oct 08 18:05:00 2016 +1100 > @@ -29,23 +29,33 @@ > { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, > { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED }, > { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, > + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, > { ngx_null_string, 0 } > }; > > > -static ngx_str_t ngx_mail_pop3_auth_plain_capability = > - ngx_string("+OK methods supported:" CRLF > - "LOGIN" CRLF > - "PLAIN" CRLF > - "." CRLF); > +static ngx_str_t ngx_mail_pop3_auth_methods_capabilities[] = { > + ngx_string("LOGIN PLAIN"), > + ngx_null_string, /* LOGIN */ > + ngx_null_string, /* APOP */ > + ngx_string("CRAM-MD5"), > + ngx_string("EXTERNAL"), > + ngx_null_string /* NONE */ > +}; > > > -static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability = > - ngx_string("+OK methods supported:" CRLF > - "LOGIN" CRLF > - "PLAIN" CRLF > - "CRAM-MD5" CRLF > - "." CRLF); > +static ngx_str_t ngx_mail_pop3_auth_methods_authnames[] = { > + ngx_string("LOGIN" CRLF "PLAIN" CRLF), > + ngx_null_string, /* LOGIN */ > + ngx_null_string, /* APOP */ > + ngx_string("CRAM-MD5" CRLF), > + ngx_string("EXTERNAL" CRLF), > + ngx_null_string /* NONE */ > +}; > + > + > +static ngx_str_t ngx_mail_pop3_auth_capability = > + ngx_string("+OK methods supported:" CRLF); It would be much easier to just have a list of method names instead, much like IMAP module do. The fact that that LOGIN is expected to be switched on along with PLAIN can be easily handled elsewhere in the code. This will result in switched order of methods ("PLAIN LOGIN" instead of "LOGIN PLAIN" used to be previously), but I don't think this is important for any reasonable client. Also, this probably should be a separate preparatory patch to simplify things. Below is the pop3 part rewritten to use just a method names (and few other style issues fixed), and your patch on top of it. # HG changeset patch # User Maxim Dounin # Date 1476333412 -10800 # Thu Oct 13 07:36:52 2016 +0300 # Node ID 6c5362af49924af0e6f478a89ffa3f1dbdae3ddd # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 Mail: extensible auth methods in pop3 module. diff --git a/src/mail/ngx_mail_pop3_module.c b/src/mail/ngx_mail_pop3_module.c --- a/src/mail/ngx_mail_pop3_module.c +++ b/src/mail/ngx_mail_pop3_module.c @@ -33,19 +33,13 @@ static ngx_conf_bitmask_t ngx_mail_pop3 }; -static ngx_str_t ngx_mail_pop3_auth_plain_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "." CRLF); - - -static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "CRAM-MD5" CRLF - "." CRLF); +static ngx_str_t ngx_mail_pop3_auth_methods_names[] = { + ngx_string("PLAIN"), + ngx_string("LOGIN"), + ngx_null_string, /* APOP */ + ngx_string("CRAM-MD5"), + ngx_null_string /* NONE */ +}; static ngx_mail_protocol_t ngx_mail_pop3_protocol = { @@ -140,13 +134,17 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t u_char *p; size_t size, stls_only_size; ngx_str_t *c, *d; - ngx_uint_t i; + ngx_uint_t i, m; ngx_conf_merge_bitmask_value(conf->auth_methods, prev->auth_methods, (NGX_CONF_BITMASK_SET |NGX_MAIL_AUTH_PLAIN_ENABLED)); + if (conf->auth_methods & NGX_MAIL_AUTH_PLAIN_ENABLED) { + conf->auth_methods |= NGX_MAIL_AUTH_LOGIN_ENABLED; + } + if (conf->capabilities.nelts == 0) { conf->capabilities = prev->capabilities; } @@ -179,11 +177,15 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t stls_only_size += c[i].len + sizeof(CRLF) - 1; } - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; + size += sizeof("SASL") - 1 + sizeof(CRLF) - 1; - } else { - size += sizeof("SASL LOGIN PLAIN" CRLF) - 1; + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + size += 1 + ngx_mail_pop3_auth_methods_names[i].len; + } } p = ngx_pnalloc(cf->pool, size); @@ -202,15 +204,21 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *p++ = CR; *p++ = LF; } - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF, - sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1); + p = ngx_cpymem(p, "SASL", sizeof("SASL") - 1); - } else { - p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF, - sizeof("SASL LOGIN PLAIN" CRLF) - 1); + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + *p++ = ' '; + p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data, + ngx_mail_pop3_auth_methods_names[i].len); + } } + *p++ = CR; *p++ = LF; + *p++ = '.'; *p++ = CR; *p = LF; @@ -231,13 +239,43 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *p++ = '.'; *p++ = CR; *p = LF; - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability; + size = sizeof("+OK methods supported:" CRLF) - 1 + + sizeof("." CRLF) - 1; - } else { - conf->auth_capability = ngx_mail_pop3_auth_plain_capability; + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + size += ngx_mail_pop3_auth_methods_names[i].len + + sizeof(CRLF) - 1; + } } + p = ngx_pnalloc(cf->pool, size); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + conf->auth_capability.data = p; + conf->auth_capability.len = size; + + p = ngx_cpymem(p, "+OK methods supported:" CRLF, + sizeof("+OK methods supported:" CRLF) - 1); + + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data, + ngx_mail_pop3_auth_methods_names[i].len); + *p++ = CR; *p++ = LF; + } + } + + *p++ = '.'; *p++ = CR; *p = LF; + p = ngx_pnalloc(cf->pool, stls_only_size); if (p == NULL) { # HG changeset patch # User Rob N ? # Date 1475910300 -39600 # Sat Oct 08 18:05:00 2016 +1100 # Node ID 63ed6c3acaa00c348d91ec84436fa05bd4afc96b # Parent 6c5362af49924af0e6f478a89ffa3f1dbdae3ddd Mail: support SASL EXTERNAL (RFC 4422). This is needed to allow TLS client certificate auth to work. With ssl_verify_client configured, the auth daemon can choose to allow the connection to proceed based on the certificate data. This has been tested with Thunderbird for IMAP only. I've not yet found a client that will do client certificate auth for POP3 or SMTP, and the method is not really documented anywhere that I can find. That said, its simple enough that the way I've done is probably right. diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -132,7 +132,8 @@ typedef enum { ngx_pop3_auth_login_username, ngx_pop3_auth_login_password, ngx_pop3_auth_plain, - ngx_pop3_auth_cram_md5 + ngx_pop3_auth_cram_md5, + ngx_pop3_auth_external } ngx_pop3_state_e; @@ -142,6 +143,7 @@ typedef enum { ngx_imap_auth_login_password, ngx_imap_auth_plain, ngx_imap_auth_cram_md5, + ngx_imap_auth_external, ngx_imap_login, ngx_imap_user, ngx_imap_passwd @@ -154,6 +156,7 @@ typedef enum { ngx_smtp_auth_login_password, ngx_smtp_auth_plain, ngx_smtp_auth_cram_md5, + ngx_smtp_auth_external, ngx_smtp_helo, ngx_smtp_helo_xclient, ngx_smtp_helo_from, @@ -285,14 +288,16 @@ typedef struct { #define NGX_MAIL_AUTH_LOGIN_USERNAME 2 #define NGX_MAIL_AUTH_APOP 3 #define NGX_MAIL_AUTH_CRAM_MD5 4 -#define NGX_MAIL_AUTH_NONE 5 +#define NGX_MAIL_AUTH_EXTERNAL 5 +#define NGX_MAIL_AUTH_NONE 6 #define NGX_MAIL_AUTH_PLAIN_ENABLED 0x0002 #define NGX_MAIL_AUTH_LOGIN_ENABLED 0x0004 #define NGX_MAIL_AUTH_APOP_ENABLED 0x0008 #define NGX_MAIL_AUTH_CRAM_MD5_ENABLED 0x0010 -#define NGX_MAIL_AUTH_NONE_ENABLED 0x0020 +#define NGX_MAIL_AUTH_EXTERNAL_ENABLED 0x0020 +#define NGX_MAIL_AUTH_NONE_ENABLED 0x0040 #define NGX_MAIL_PARSE_INVALID_COMMAND 20 @@ -377,6 +382,8 @@ ngx_int_t ngx_mail_auth_login_password(n ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c, char *prefix, size_t len); ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c); +ngx_int_t ngx_mail_auth_external(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n); ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c); void ngx_mail_send(ngx_event_t *wev); diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c +++ b/src/mail/ngx_mail_auth_http_module.c @@ -151,6 +151,7 @@ static ngx_str_t ngx_mail_auth_http_me ngx_string("plain"), ngx_string("apop"), ngx_string("cram-md5"), + ngx_string("external"), ngx_string("none") }; diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -612,6 +612,40 @@ ngx_mail_auth_cram_md5(ngx_mail_session_ } +ngx_int_t +ngx_mail_auth_external(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n) +{ + ngx_str_t *arg, external; + + arg = s->args.elts; + + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, + "mail auth external: \"%V\"", &arg[n]); + + external.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len)); + if (external.data == NULL) { + return NGX_ERROR; + } + + if (ngx_decode_base64(&external, &arg[n]) != NGX_OK) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent invalid base64 encoding in AUTH EXTERNAL command"); + return NGX_MAIL_PARSE_INVALID_COMMAND; + } + + s->login.len = external.len; + s->login.data = external.data; + + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, + "mail auth external: \"%V\"", &s->login); + + s->auth_method = NGX_MAIL_AUTH_EXTERNAL; + + return NGX_DONE; +} + + void ngx_mail_send(ngx_event_t *wev) { diff --git a/src/mail/ngx_mail_imap_handler.c b/src/mail/ngx_mail_imap_handler.c --- a/src/mail/ngx_mail_imap_handler.c +++ b/src/mail/ngx_mail_imap_handler.c @@ -222,6 +222,10 @@ ngx_mail_imap_auth_state(ngx_event_t *re case ngx_imap_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_imap_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } else if (rc == NGX_IMAP_NEXT) { @@ -399,6 +403,13 @@ ngx_mail_imap_authenticate(ngx_mail_sess } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, imap_username); + s->mail_state = ngx_imap_auth_external; + + return NGX_OK; } return rc; diff --git a/src/mail/ngx_mail_imap_module.c b/src/mail/ngx_mail_imap_module.c --- a/src/mail/ngx_mail_imap_module.c +++ b/src/mail/ngx_mail_imap_module.c @@ -29,6 +29,7 @@ static ngx_conf_bitmask_t ngx_mail_imap { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_null_string, 0 } }; @@ -38,6 +39,7 @@ static ngx_str_t ngx_mail_imap_auth_met ngx_string("AUTH=LOGIN"), ngx_null_string, /* APOP */ ngx_string("AUTH=CRAM-MD5"), + ngx_string("AUTH=EXTERNAL"), ngx_null_string /* NONE */ }; @@ -179,7 +181,7 @@ ngx_mail_imap_merge_srv_conf(ngx_conf_t } for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -205,7 +207,7 @@ ngx_mail_imap_merge_srv_conf(ngx_conf_t auth = p; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c --- a/src/mail/ngx_mail_parse.c +++ b/src/mail/ngx_mail_parse.c @@ -905,13 +905,27 @@ ngx_mail_auth_parse(ngx_mail_session_t * if (arg[0].len == 8) { - if (s->args.nelts != 1) { - return NGX_MAIL_PARSE_INVALID_COMMAND; + if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) { + + if (s->args.nelts != 1) { + return NGX_MAIL_PARSE_INVALID_COMMAND; + } + + return NGX_MAIL_AUTH_CRAM_MD5; } - if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) { - return NGX_MAIL_AUTH_CRAM_MD5; + if (ngx_strncasecmp(arg[0].data, (u_char *) "EXTERNAL", 8) == 0) { + + if (s->args.nelts == 1) { + return NGX_MAIL_AUTH_EXTERNAL; + } + + if (s->args.nelts == 2) { + return ngx_mail_auth_external(s, c, 1); + } } + + return NGX_MAIL_PARSE_INVALID_COMMAND; } return NGX_MAIL_PARSE_INVALID_COMMAND; diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c +++ b/src/mail/ngx_mail_pop3_handler.c @@ -240,6 +240,10 @@ ngx_mail_pop3_auth_state(ngx_event_t *re case ngx_pop3_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_pop3_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } @@ -494,6 +498,13 @@ ngx_mail_pop3_auth(ngx_mail_session_t *s } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, pop3_username); + s->mail_state = ngx_pop3_auth_external; + + return NGX_OK; } return rc; diff --git a/src/mail/ngx_mail_pop3_module.c b/src/mail/ngx_mail_pop3_module.c --- a/src/mail/ngx_mail_pop3_module.c +++ b/src/mail/ngx_mail_pop3_module.c @@ -29,6 +29,7 @@ static ngx_conf_bitmask_t ngx_mail_pop3 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_null_string, 0 } }; @@ -38,6 +39,7 @@ static ngx_str_t ngx_mail_pop3_auth_met ngx_string("LOGIN"), ngx_null_string, /* APOP */ ngx_string("CRAM-MD5"), + ngx_string("EXTERNAL"), ngx_null_string /* NONE */ }; @@ -180,7 +182,7 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t size += sizeof("SASL") - 1 + sizeof(CRLF) - 1; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -207,7 +209,7 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t p = ngx_cpymem(p, "SASL", sizeof("SASL") - 1); for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -243,7 +245,7 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t + sizeof("." CRLF) - 1; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -264,7 +266,7 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t sizeof("+OK methods supported:" CRLF) - 1); for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c +++ b/src/mail/ngx_mail_smtp_handler.c @@ -485,6 +485,10 @@ ngx_mail_smtp_auth_state(ngx_event_t *re case ngx_smtp_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_smtp_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } @@ -652,6 +656,13 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, smtp_username); + s->mail_state = ngx_smtp_auth_external; + + return NGX_OK; } return rc; diff --git a/src/mail/ngx_mail_smtp_module.c b/src/mail/ngx_mail_smtp_module.c --- a/src/mail/ngx_mail_smtp_module.c +++ b/src/mail/ngx_mail_smtp_module.c @@ -21,6 +21,7 @@ static ngx_conf_bitmask_t ngx_mail_smtp { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_string("none"), NGX_MAIL_AUTH_NONE_ENABLED }, { ngx_null_string, 0 } }; @@ -31,6 +32,7 @@ static ngx_str_t ngx_mail_smtp_auth_met ngx_string("LOGIN"), ngx_null_string, /* APOP */ ngx_string("CRAM-MD5"), + ngx_string("EXTERNAL"), ngx_null_string /* NONE */ }; @@ -207,7 +209,7 @@ ngx_mail_smtp_merge_srv_conf(ngx_conf_t auth_enabled = 0; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -250,7 +252,7 @@ ngx_mail_smtp_merge_srv_conf(ngx_conf_t *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H'; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { -- Maxim Dounin http://nginx.org/ From llz at antiy.cn Thu Oct 13 05:55:09 2016 From: llz at antiy.cn (=?UTF-8?B?5p2O5p6X5ZOy?=) Date: Thu, 13 Oct 2016 13:55:09 +0800 Subject: =?UTF-8?Q?patch_purpose//Re=EF=BC=9A=5Bpatch=5Dfork=3A_subprocess_quit_whe?= =?UTF-8?Q?n_parent_died?= Message-ID: <0d8ec13b-0cc0-4f6b-bbfa-74a636a5ccbe.llz@antiy.cn> Hi, ZhiDao.? If master dies often as you said, I believe community shell treat it as a bug and fix it ASAP.? Personally I won't meet it frequently. Only at when system OOM or user misoperation.?Thanks.? -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Oct 13 06:07:07 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 13 Oct 2016 09:07:07 +0300 Subject: =?UTF-8?Q?Re=3A_patch_purpose//Re=EF=BC=9A=5Bpatch=5Dfork=3A_subprocess_qu?= =?UTF-8?Q?it_when_parent_died?= In-Reply-To: <9cf63f5f-f639-4e91-a6f3-e045dde08667.llz@antiy.cn> References: <9cf63f5f-f639-4e91-a6f3-e045dde08667.llz@antiy.cn> Message-ID: <20161013060707.GQ73038@mdounin.ru> Hello! On Thu, Oct 13, 2016 at 01:46:28PM +0800, ??? wrote: > Hi, Maxim.?When master OOM, system daemon program like > supervisord will trying to pull it up. but it can?t be > done because of worker binds the port. This is because the service is still running. And, as we can see from the answer, this behaviour only make sense if nginx is controlled using supervisord. And even in this case it's questionable behaviour - because, again, the service is still running, and potentially important connections are still established. No, thanks, the patch won't be accepted. -- Maxim Dounin http://nginx.org/ From hucong.c at foxmail.com Thu Oct 13 08:45:23 2016 From: hucong.c at foxmail.com (=?gb18030?B?1MK2+g==?=) Date: Thu, 13 Oct 2016 16:45:23 +0800 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. Message-ID: # HG changeset patch # User hucongcong # Date 1476342771 -28800 # Thu Oct 13 15:12:51 2016 +0800 # Node ID 93bad8b82169245db6d4fe4e6b6c823221ee6a38 # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 Http mp4: replace strtod() with improved ngx_atofp() because precision problem. function prototype is ngx_atofp(u_char *line, size_t n, size_t point). use case based on the old version: ngx_atofp("12.2193", 7, 0) returns NGX_ERROR, ngx_atofp("12.2193", 7, 2) returns NGX_ERROR. now, allow point = 0 or point less than the number of fractional digits. ngx_atofp("12.2193", 7, 0) returns 12, ngx_atofp("12.2193", 7, 2) returns 1221. retained all the required or right feature at the same time, e.g., ngx_atofp("10.5", 4, 2) returns 1050. deprecated strtod() in ngx_http_mp4_module, since the precision problem, which was metioned in http://stackoverflow.com/questions/18361261, e.g., (int) (strtod((char *) "32.480", NULL) * 1000) returns 32479. another way to solve this problem is like this round(strtod()), e.g., (int) round((strtod((char *) "32.480", NULL) * 1000)) returns 32480, but its not necessary, since we have a better ngx_atofp(). diff -r 7cdf69d012f0 -r 93bad8b82169 src/core/ngx_string.c --- a/src/core/ngx_string.c Tue Oct 11 18:03:01 2016 +0300 +++ b/src/core/ngx_string.c Thu Oct 13 15:12:51 2016 +0800 @@ -945,8 +945,8 @@ for (value = 0; n--; line++) { - if (point == 0) { - return NGX_ERROR; + if (dot && point == 0) { + break; } if (*line == '.') { diff -r 7cdf69d012f0 -r 93bad8b82169 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Tue Oct 11 18:03:01 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Thu Oct 13 15:12:51 2016 +0800 @@ -535,28 +535,14 @@ if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) { - /* - * A Flash player may send start value with a lot of digits - * after dot so strtod() is used instead of atofp(). NaNs and - * infinities become negative numbers after (int) conversion. - */ - - ngx_set_errno(0); - start = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - start = -1; - } + /* start = -1 when NGX_ERROR returned by ngx_atofp */ + + start = ngx_atofp(value.data, value.len, 3); } if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) { - ngx_set_errno(0); - end = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - end = -1; - } + end = ngx_atofp(value.data, value.len, 3); if (end > 0) { if (start < 0) { From francois.berenger at inria.fr Thu Oct 13 09:20:24 2016 From: francois.berenger at inria.fr (Francois BERENGER) Date: Thu, 13 Oct 2016 11:20:24 +0200 Subject: question about how to use the ngx_radix_tree In-Reply-To: <6a24d3ec-7f63-2916-9034-758380957e5e@inria.fr> References: <6a24d3ec-7f63-2916-9034-758380957e5e@inria.fr> Message-ID: <3e641364-dac5-1d1c-67e5-376b3b8ab630@inria.fr> On 10/12/2016 05:53 PM, Francois BERENGER wrote: > Dear list, > > I am interested in using this data structure. > > Would it be possible to have a few usage examples of it? > I looked in the nginx code via github but found only > few usages and not very informative about how to use it properly. > > I am interested in those functions: > ngx_radix_tree_t *ngx_radix_tree_create(ngx_int_t preallocate); > > ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree, > uint32_t key, uint32_t mask, > uintptr_t value); > ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree, > uint32_t key, uint32_t mask); > uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key); > > Especially, in insert and delete I don't know what should be the value > of the mask parameter. All ones seems fine in my tests. Sorry for the noise. > Should I compute this mask? How? > > Thanks a lot, > Francois. > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Regards, Francois. "When in doubt, use more types" From robn at fastmail.com Thu Oct 13 09:51:41 2016 From: robn at fastmail.com (=?UTF-8?Q?Rob=20N=20=E2=98=85?=) Date: Thu, 13 Oct 2016 20:51:41 +1100 Subject: [PATCH] Mail: Support SASL EXTERNAL (RFC 4422) In-Reply-To: <20161013055029.GP73038@mdounin.ru> References: <205f2148260460379f9b.1475911862@lena> <20161013055029.GP73038@mdounin.ru> Message-ID: <1476352301.1162324.754579193.2E4172EB@webmail.messagingengine.com> On Thu, 13 Oct 2016, at 04:50 PM, Maxim Dounin wrote: > Thank you for the patch. Overral it looks good, though there are > some things I would like to do differently in the pop3 module. > See below. Thanks, both of the things you addressed (the single list of methods, and splitting it into two patches) are things that I thought about but did end up doing. I'm glad you did! I don't anticipate any issues with swapping LOGIN and PLAIN either.. I've read both patches and both look good to me! Cheers, Rob N. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Thu Oct 13 14:30:05 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 13 Oct 2016 14:30:05 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/79ac653ae2d0 branches: changeset: 6741:79ac653ae2d0 user: Ruslan Ermilov date: Thu Oct 13 15:35:48 2016 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 7cdf69d012f0 -r 79ac653ae2d0 src/core/nginx.h --- a/src/core/nginx.h Tue Oct 11 18:03:01 2016 +0300 +++ b/src/core/nginx.h Thu Oct 13 15:35:48 2016 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1011005 -#define NGINX_VERSION "1.11.5" +#define nginx_version 1011006 +#define NGINX_VERSION "1.11.6" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From ru at nginx.com Thu Oct 13 14:30:07 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 13 Oct 2016 14:30:07 +0000 Subject: [nginx] Cache: cache manager debugging. Message-ID: details: http://hg.nginx.org/nginx/rev/3fbb3bdff824 branches: changeset: 6742:3fbb3bdff824 user: Ruslan Ermilov date: Thu Oct 13 15:50:36 2016 +0300 description: Cache: cache manager debugging. diffstat: src/http/ngx_http_file_cache.c | 38 ++++++++++++++++++++++++++------------ 1 files changed, 26 insertions(+), 12 deletions(-) diffs (79 lines): diff -r 79ac653ae2d0 -r 3fbb3bdff824 src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Thu Oct 13 15:35:48 2016 +0300 +++ b/src/http/ngx_http_file_cache.c Thu Oct 13 15:50:36 2016 +0300 @@ -1920,17 +1920,18 @@ ngx_http_file_cache_manager(void *data) ngx_http_file_cache_t *cache = data; off_t size; - time_t next, wait; - ngx_msec_t elapsed; + time_t wait; + ngx_msec_t elapsed, next; ngx_uint_t count, watermark; cache->last = ngx_current_msec; cache->files = 0; - next = ngx_http_file_cache_expire(cache); + next = (ngx_msec_t) ngx_http_file_cache_expire(cache) * 1000; if (next == 0) { - return cache->manager_sleep; + next = cache->manager_sleep; + goto done; } for ( ;; ) { @@ -1947,31 +1948,44 @@ ngx_http_file_cache_manager(void *data) size, count, (ngx_int_t) watermark); if (size < cache->max_size && count < watermark) { - return (ngx_msec_t) next * 1000; + break; } wait = ngx_http_file_cache_forced_expire(cache); if (wait > 0) { - return (ngx_msec_t) wait * 1000; + next = (ngx_msec_t) wait * 1000; + break; } if (ngx_quit || ngx_terminate) { - return (ngx_msec_t) next * 1000; - } - - if (++cache->files >= cache->manager_files) { - return cache->manager_sleep; + break; } + if (++cache->files >= cache->manager_files) { + next = cache->manager_sleep; + break; + } + ngx_time_update(); elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last)); if (elapsed >= cache->manager_threshold) { - return cache->manager_sleep; + next = cache->manager_sleep; + break; } } + +done: + + elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last)); + + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "http file cache manager: %ui e:%M n:%M", + cache->files, elapsed, next); + + return next; } From mdounin at mdounin.ru Fri Oct 14 18:13:53 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 14 Oct 2016 18:13:53 +0000 Subject: [nginx] Style. Message-ID: details: http://hg.nginx.org/nginx/rev/7fc16ff7ddc4 branches: changeset: 6743:7fc16ff7ddc4 user: Maxim Dounin date: Fri Oct 14 19:48:26 2016 +0300 description: Style. diffstat: src/core/ngx_hash.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff --git a/src/core/ngx_hash.c b/src/core/ngx_hash.c --- a/src/core/ngx_hash.c +++ b/src/core/ngx_hash.c @@ -390,7 +390,6 @@ found: buckets[i] = (ngx_hash_elt_t *) elts; elts += test[i]; - } for (i = 0; i < size; i++) { From mdounin at mdounin.ru Fri Oct 14 18:13:56 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 14 Oct 2016 18:13:56 +0000 Subject: [nginx] Upstream: hide_headers_hash inherited regardless of cache settings. Message-ID: details: http://hg.nginx.org/nginx/rev/7e5199f172fb branches: changeset: 6744:7e5199f172fb user: Maxim Dounin date: Fri Oct 14 19:48:26 2016 +0300 description: Upstream: hide_headers_hash inherited regardless of cache settings. Dependency on cache settings existed prior to 2728c4e4a9ae (0.8.44) as Set-Cookie header was automatically hidden from responses when using cache. This is no longer the case, and hide_headers_hash can be safely inherited regardless of cache settings. diffstat: src/http/ngx_http_upstream.c | 7 +------ 1 files changed, 1 insertions(+), 6 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 @@ -6021,12 +6021,7 @@ ngx_http_upstream_hide_headers_hash(ngx_ conf->hide_headers_hash = prev->hide_headers_hash; - if (conf->hide_headers_hash.buckets -#if (NGX_HTTP_CACHE) - && ((conf->cache == 0) == (prev->cache == 0)) -#endif - ) - { + if (conf->hide_headers_hash.buckets) { return NGX_OK; } From mdounin at mdounin.ru Fri Oct 14 18:13:58 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 14 Oct 2016 18:13:58 +0000 Subject: [nginx] Upstream: hide_headers_hash handling at http level. Message-ID: details: http://hg.nginx.org/nginx/rev/93121485c39b branches: changeset: 6745:93121485c39b user: Maxim Dounin date: Fri Oct 14 19:48:26 2016 +0300 description: Upstream: hide_headers_hash handling at http level. When headers to hide are set at the "http" level and not redefined in a server block, we now preserve compiled headers hash into the "http" section configuration to inherit this hash to all servers. diffstat: src/http/ngx_http_upstream.c | 18 +++++++++++++++++- 1 files changed, 17 insertions(+), 1 deletions(-) diffs (28 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 @@ -6106,7 +6106,23 @@ ngx_http_upstream_hide_headers_hash(ngx_ hash->pool = cf->pool; hash->temp_pool = NULL; - return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts); + if (ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) { + return NGX_ERROR; + } + + /* + * special handling to preserve conf->hide_headers_hash + * in the "http" section to inherit it to all servers + */ + + if (prev->hide_headers_hash.buckets == NULL + && conf->hide_headers == prev->hide_headers + && conf->pass_headers == prev->pass_headers) + { + prev->hide_headers_hash = conf->hide_headers_hash; + } + + return NGX_OK; } From mdounin at mdounin.ru Fri Oct 14 18:14:00 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 14 Oct 2016 18:14:00 +0000 Subject: [nginx] Proxy: do not create conf->headers_source when not needed. Message-ID: details: http://hg.nginx.org/nginx/rev/63991ab67b3a branches: changeset: 6746:63991ab67b3a user: Maxim Dounin date: Fri Oct 14 19:48:26 2016 +0300 description: Proxy: do not create conf->headers_source when not needed. diffstat: src/http/modules/ngx_http_proxy_module.c | 27 +++++++++++---------------- 1 files changed, 11 insertions(+), 16 deletions(-) diffs (45 lines): diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -3392,14 +3392,6 @@ ngx_http_proxy_init_headers(ngx_conf_t * return NGX_ERROR; } - if (conf->headers_source == NULL) { - conf->headers_source = ngx_array_create(cf->pool, 4, - sizeof(ngx_keyval_t)); - if (conf->headers_source == NULL) { - return NGX_ERROR; - } - } - headers->lengths = ngx_array_create(cf->pool, 64, 1); if (headers->lengths == NULL) { return NGX_ERROR; @@ -3410,15 +3402,18 @@ ngx_http_proxy_init_headers(ngx_conf_t * return NGX_ERROR; } - src = conf->headers_source->elts; - for (i = 0; i < conf->headers_source->nelts; i++) { - - s = ngx_array_push(&headers_merged); - if (s == NULL) { - return NGX_ERROR; + if (conf->headers_source) { + + src = conf->headers_source->elts; + for (i = 0; i < conf->headers_source->nelts; i++) { + + s = ngx_array_push(&headers_merged); + if (s == NULL) { + return NGX_ERROR; + } + + *s = src[i]; } - - *s = src[i]; } h = default_headers; From mdounin at mdounin.ru Fri Oct 14 18:14:03 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 14 Oct 2016 18:14:03 +0000 Subject: [nginx] Upstream: handling of proxy_set_header at http level. Message-ID: details: http://hg.nginx.org/nginx/rev/20eb4587225b branches: changeset: 6747:20eb4587225b user: Maxim Dounin date: Fri Oct 14 19:48:26 2016 +0300 description: Upstream: handling of proxy_set_header at http level. When headers are set at the "http" level and not redefined in a server block, we now preserve conf->headers into the "http" section configuration to inherit it to all servers. The same applies to conf->headers_cache, though it may not be effective if no servers use cache at the "server" level as conf->headers_cache is only initialized if cache is enabled on a given level. Similar changes made in fastcgi/scgi/uwsgi to preserve conf->params and conf->params_cache. diffstat: src/http/modules/ngx_http_fastcgi_module.c | 14 ++++++++++++++ src/http/modules/ngx_http_proxy_module.c | 14 ++++++++++++++ src/http/modules/ngx_http_scgi_module.c | 14 ++++++++++++++ src/http/modules/ngx_http_uwsgi_module.c | 14 ++++++++++++++ 4 files changed, 56 insertions(+), 0 deletions(-) diffs (96 lines): diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -3127,6 +3127,20 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf #endif + /* + * special handling to preserve conf->params in the "http" section + * to inherit it to all servers + */ + + if (prev->params.hash.buckets == NULL + && conf->params_source == prev->params_source) + { + prev->params = conf->params; +#if (NGX_HTTP_CACHE) + prev->params_cache = conf->params_cache; +#endif + } + return NGX_CONF_OK; } diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -3357,6 +3357,20 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t #endif + /* + * special handling to preserve conf->headers in the "http" section + * to inherit it to all servers + */ + + if (prev->headers.hash.buckets == NULL + && conf->headers_source == prev->headers_source) + { + prev->headers = conf->headers; +#if (NGX_HTTP_CACHE) + prev->headers_cache = conf->headers_cache; +#endif + } + return NGX_CONF_OK; } diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -1558,6 +1558,20 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t #endif + /* + * special handling to preserve conf->params in the "http" section + * to inherit it to all servers + */ + + if (prev->params.hash.buckets == NULL + && conf->params_source == prev->params_source) + { + prev->params = conf->params; +#if (NGX_HTTP_CACHE) + prev->params_cache = conf->params_cache; +#endif + } + return NGX_CONF_OK; } diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -1820,6 +1820,20 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t #endif + /* + * special handling to preserve conf->params in the "http" section + * to inherit it to all servers + */ + + if (prev->params.hash.buckets == NULL + && conf->params_source == prev->params_source) + { + prev->params = conf->params; +#if (NGX_HTTP_CACHE) + prev->params_cache = conf->params_cache; +#endif + } + return NGX_CONF_OK; } From piotrsikora at google.com Mon Oct 17 07:29:40 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 17 Oct 2016 00:29:40 -0700 Subject: [PATCH] Remove duplicate implementation of njs_parser_token() Message-ID: <11abc80a5a442b56ee06.1476689380@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1476689340 25200 # Mon Oct 17 00:29:00 2016 -0700 # Node ID 11abc80a5a442b56ee0618834b88510369a765d6 # Parent 8046b999aaaf95980e89a6d0620657bc4123342b Remove duplicate implementation of njs_parser_token(). Signed-off-by: Piotr Sikora diff -r 8046b999aaaf -r 11abc80a5a44 njs/njs_nonrecursive_parser.c --- a/njs/njs_nonrecursive_parser.c +++ b/njs/njs_nonrecursive_parser.c @@ -116,24 +116,6 @@ njs_nonrecursive_parser(njs_vm_t *vm, nj } -njs_token_t -njs_parser_token(njs_parser_t *parser) -{ - njs_token_t token; - - do { - token = njs_lexer_token(parser->lexer); - - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - return token; - } - - } while (nxt_slow_path(token == NJS_TOKEN_LINE_END)); - - return token; -} - - static void * njs_parser_stack_pop(njs_parser_t *parser) { From hongzhidao at gmail.com Mon Oct 17 08:25:37 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Mon, 17 Oct 2016 16:25:37 +0800 Subject: [PATCH] Remove duplicate implementation of njs_parser_token() In-Reply-To: <11abc80a5a442b56ee06.1476689380@piotrsikora.sfo.corp.google.com> References: <11abc80a5a442b56ee06.1476689380@piotrsikora.sfo.corp.google.com> Message-ID: Hello! It seems the file njs/njs_nonrecursive_parser.c is unused. 2016-10-17 15:29 GMT+08:00 Piotr Sikora : > # HG changeset patch > # User Piotr Sikora > # Date 1476689340 25200 > # Mon Oct 17 00:29:00 2016 -0700 > # Node ID 11abc80a5a442b56ee0618834b88510369a765d6 > # Parent 8046b999aaaf95980e89a6d0620657bc4123342b > Remove duplicate implementation of njs_parser_token(). > > Signed-off-by: Piotr Sikora > > diff -r 8046b999aaaf -r 11abc80a5a44 njs/njs_nonrecursive_parser.c > --- a/njs/njs_nonrecursive_parser.c > +++ b/njs/njs_nonrecursive_parser.c > @@ -116,24 +116,6 @@ njs_nonrecursive_parser(njs_vm_t *vm, nj > } > > > -njs_token_t > -njs_parser_token(njs_parser_t *parser) > -{ > - njs_token_t token; > - > - do { > - token = njs_lexer_token(parser->lexer); > - > - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { > - return token; > - } > - > - } while (nxt_slow_path(token == NJS_TOKEN_LINE_END)); > - > - return token; > -} > - > - > static void * > njs_parser_stack_pop(njs_parser_t *parser) > { > > _______________________________________________ > 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 piotrsikora at google.com Mon Oct 17 08:34:41 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 17 Oct 2016 01:34:41 -0700 Subject: [PATCH] Remove duplicate implementation of njs_parser_token() In-Reply-To: References: <11abc80a5a442b56ee06.1476689380@piotrsikora.sfo.corp.google.com> Message-ID: Hello, > It seems the file njs/njs_nonrecursive_parser.c is unused. It's linked as part of libnjs.a, so it's kind of used... Whether it should be linked in the first place, that's question for Igor. Best regards, Piotr Sikora From igor at sysoev.ru Mon Oct 17 09:30:07 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 17 Oct 2016 12:30:07 +0300 Subject: [PATCH] Remove duplicate implementation of njs_parser_token() In-Reply-To: References: <11abc80a5a442b56ee06.1476689380@piotrsikora.sfo.corp.google.com> Message-ID: <401E1F30-3A42-4770-BD00-0F170CC5712F@sysoev.ru> On 17 Oct 2016, at 11:25, ??? wrote: > Hello! > > It seems the file njs/njs_nonrecursive_parser.c is unused. Yes, I?m going to remove it. -- Igor Sysoev http://nginx.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From piotrsikora at google.com Mon Oct 17 10:06:42 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 17 Oct 2016 03:06:42 -0700 Subject: [PATCH] Configure: fix build with -Werror=return-type Message-ID: # HG changeset patch # User Piotr Sikora # Date 1476698417 25200 # Mon Oct 17 03:00:17 2016 -0700 # Node ID ad0525e40183deb5dc2d5f1f85ee3f28c0762249 # Parent 8046b999aaaf95980e89a6d0620657bc4123342b Configure: fix build with -Werror=return-type. Signed-off-by: Piotr Sikora diff -r 8046b999aaaf -r ad0525e40183 nxt/auto/clang --- a/nxt/auto/clang +++ b/nxt/auto/clang @@ -198,6 +198,7 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="int main() { __builtin_prefetch(0); + return 0; }" . ${NXT_AUTO}feature From piotrsikora at google.com Mon Oct 17 10:06:55 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 17 Oct 2016 03:06:55 -0700 Subject: [PATCH] Configure: fix build with -Werror=old-style-definition Message-ID: # HG changeset patch # User Piotr Sikora # Date 1476698419 25200 # Mon Oct 17 03:00:19 2016 -0700 # Node ID ec3df1ebada2b25409fcba4502f1267640f43a76 # Parent 8046b999aaaf95980e89a6d0620657bc4123342b Configure: fix build with -Werror=old-style-definition. Signed-off-by: Piotr Sikora diff -r 8046b999aaaf -r ec3df1ebada2 nxt/auto/clang --- a/nxt/auto/clang +++ b/nxt/auto/clang @@ -185,7 +185,7 @@ nxt_feature_name=NXT_HAVE_BUILTIN_UNREAC nxt_feature_run=no nxt_feature_incs= nxt_feature_libs= -nxt_feature_test="int main() { +nxt_feature_test="int main(void) { __builtin_unreachable(); }" . ${NXT_AUTO}feature @@ -196,7 +196,7 @@ nxt_feature_name=NXT_HAVE_BUILTIN_PREFET nxt_feature_run=no nxt_feature_incs= nxt_feature_libs= -nxt_feature_test="int main() { +nxt_feature_test="int main(void) { __builtin_prefetch(0); }" . ${NXT_AUTO}feature @@ -209,7 +209,7 @@ nxt_feature_path= nxt_feature_libs= nxt_feature_test="int n __attribute__ ((visibility(\"default\"))); - int main() { + int main(void) { return 1; }" . ${NXT_AUTO}feature @@ -228,7 +228,7 @@ nxt_feature_test="#include return malloc(1); } - int main() { + int main(void) { if (f() != NULL) { return 1; } @@ -255,7 +255,7 @@ else nxt_feature_libs= nxt_feature_test="int n __attribute__ ((aligned(64))); - int main() { + int main(void) { return 1; }" . ${NXT_AUTO}feature diff -r 8046b999aaaf -r ec3df1ebada2 nxt/auto/getrandom --- a/nxt/auto/getrandom +++ b/nxt/auto/getrandom @@ -14,7 +14,7 @@ nxt_feature_test="#include #include #include - int main() { + int main(void) { char buf[4]; (void) syscall(SYS_getrandom, buf, 4, 0); diff -r 8046b999aaaf -r ec3df1ebada2 nxt/auto/memalign --- a/nxt/auto/memalign +++ b/nxt/auto/memalign @@ -13,7 +13,7 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include - int main() { + int main(void) { void *p; if (posix_memalign(&p, 4096, 4096) != 0) @@ -34,7 +34,7 @@ if [ $nxt_found = no ]; then nxt_feature_libs= nxt_feature_test="#include - int main() { + int main(void) { if (memalign(4096, 4096) == NULL) return 1; return 0; diff -r 8046b999aaaf -r ec3df1ebada2 nxt/auto/pcre --- a/nxt/auto/pcre +++ b/nxt/auto/pcre @@ -20,7 +20,7 @@ if /bin/sh -c "(pcre-config --version)" nxt_feature_libs=$NXT_PCRE_LIB nxt_feature_test="#include - int main() { + int main(void) { pcre *re; re = pcre_compile(NULL, 0, NULL, 0, NULL); diff -r 8046b999aaaf -r ec3df1ebada2 nxt/auto/time --- a/nxt/auto/time +++ b/nxt/auto/time @@ -12,7 +12,7 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include - int main() { + int main(void) { time_t t; struct tm tm; @@ -32,7 +32,7 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include - int main() { + int main(void) { altzone = 0; return 0; }" From igor at sysoev.ru Mon Oct 17 14:01:38 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 17 Oct 2016 14:01:38 +0000 Subject: [njs] A fix in Array.splice() function. Message-ID: details: http://hg.nginx.org/njs/rev/c68db870b8b0 branches: changeset: 199:c68db870b8b0 user: Igor Sysoev date: Fri Oct 14 17:21:35 2016 +0300 description: A fix in Array.splice() function. diffstat: njs/njs_array.c | 4 ++++ njs/test/njs_unit_test.c | 4 ++++ 2 files changed, 8 insertions(+), 0 deletions(-) diffs (28 lines): diff -r 8046b999aaaf -r c68db870b8b0 njs/njs_array.c --- a/njs/njs_array.c Wed Oct 12 19:08:57 2016 +0300 +++ b/njs/njs_array.c Fri Oct 14 17:21:35 2016 +0300 @@ -585,6 +585,10 @@ njs_array_prototype_splice(njs_vm_t *vm, if (nargs > 1) { start = args[1].data.u.number; + if (start > array->length) { + start = array->length; + } + if (nargs > 2) { delete = args[2].data.u.number; diff -r 8046b999aaaf -r c68db870b8b0 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Oct 12 19:08:57 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Oct 14 17:21:35 2016 +0300 @@ -2304,6 +2304,10 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = []; a.splice()"), nxt_string("") }, + { nxt_string("var a = [];" + "a.splice(9,0,1,2).join(':') + '|' + a"), + nxt_string("|1,2") }, + { nxt_string("var a = [0,1,2,3,4,5,6,7];" "a.splice(3).join(':') + '|' + a"), nxt_string("3:4:5:6:7|0,1,2") }, From igor at sysoev.ru Mon Oct 17 14:01:41 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 17 Oct 2016 14:01:41 +0000 Subject: [njs] A fix of var declaration. Message-ID: details: http://hg.nginx.org/njs/rev/5d08fa7106b8 branches: changeset: 200:5d08fa7106b8 user: Igor Sysoev date: Fri Oct 14 18:12:36 2016 +0300 description: A fix of var declaration. diffstat: njs/njs_parser.c | 1 + njs/test/njs_unit_test.c | 6 ++++++ 2 files changed, 7 insertions(+), 0 deletions(-) diffs (27 lines): diff -r c68db870b8b0 -r 5d08fa7106b8 njs/njs_parser.c --- a/njs/njs_parser.c Fri Oct 14 17:21:35 2016 +0300 +++ b/njs/njs_parser.c Fri Oct 14 18:12:36 2016 +0300 @@ -641,6 +641,7 @@ njs_parser_var_statement(njs_vm_t *vm, n njs_variable_t *var; njs_parser_node_t *left, *stmt, *name, *assign; + parser->node = NULL; left = NULL; do { diff -r c68db870b8b0 -r 5d08fa7106b8 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Oct 14 17:21:35 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Oct 14 18:12:36 2016 +0300 @@ -68,6 +68,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = 1; var b; a"), nxt_string("1") }, + { nxt_string("a = 1;for(;a;a--)var a; a"), + nxt_string("0") }, + + { nxt_string("if(1)if(0){0?0:0}else\nvar a\nelse\nvar b"), + nxt_string("undefined") }, + { nxt_string("function f(){} function f(){}"), nxt_string("SyntaxError: Duplicate declaration \"f\" in 1") }, From igor at sysoev.ru Mon Oct 17 14:01:42 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 17 Oct 2016 14:01:42 +0000 Subject: [njs] Object argument in some Date methods was not checked. Message-ID: details: http://hg.nginx.org/njs/rev/c583e4985a7b branches: changeset: 201:c583e4985a7b user: Igor Sysoev date: Fri Oct 14 18:21:37 2016 +0300 description: Object argument in some Date methods was not checked. diffstat: njs/njs_date.c | 83 +++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 54 insertions(+), 29 deletions(-) diffs (223 lines): diff -r 5d08fa7106b8 -r c583e4985a7b njs/njs_date.c --- a/njs/njs_date.c Fri Oct 14 18:12:36 2016 +0300 +++ b/njs/njs_date.c Fri Oct 14 18:21:37 2016 +0300 @@ -1909,165 +1909,190 @@ static const njs_object_prop_t njs_date { .type = NJS_METHOD, .name = njs_string("valueOf"), - .value = njs_native_function(njs_date_prototype_value_of, 0, 0), + .value = njs_native_function(njs_date_prototype_value_of, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("toString"), - .value = njs_native_function(njs_date_prototype_to_string, 0, 0), + .value = njs_native_function(njs_date_prototype_to_string, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("toDateString"), - .value = njs_native_function(njs_date_prototype_to_date_string, 0, 0), + .value = njs_native_function(njs_date_prototype_to_date_string, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("toTimeString"), - .value = njs_native_function(njs_date_prototype_to_time_string, 0, 0), + .value = njs_native_function(njs_date_prototype_to_time_string, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("toLocaleString"), - .value = njs_native_function(njs_date_prototype_to_string, 0, 0), + .value = njs_native_function(njs_date_prototype_to_string, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_long_string("toLocaleDateString"), - .value = njs_native_function(njs_date_prototype_to_date_string, 0, 0), + .value = njs_native_function(njs_date_prototype_to_date_string, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_long_string("toLocaleTimeString"), - .value = njs_native_function(njs_date_prototype_to_time_string, 0, 0), + .value = njs_native_function(njs_date_prototype_to_time_string, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("toUTCString"), - .value = njs_native_function(njs_date_prototype_to_utc_string, 0, 0), + .value = njs_native_function(njs_date_prototype_to_utc_string, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("toISOString"), - .value = njs_native_function(njs_date_prototype_to_iso_string, 0, 0), + .value = njs_native_function(njs_date_prototype_to_iso_string, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getTime"), - .value = njs_native_function(njs_date_prototype_value_of, 0, 0), + .value = njs_native_function(njs_date_prototype_value_of, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getFullYear"), - .value = njs_native_function(njs_date_prototype_get_full_year, 0, 0), + .value = njs_native_function(njs_date_prototype_get_full_year, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getUTCFullYear"), - .value = njs_native_function(njs_date_prototype_get_utc_full_year, - 0, 0), + .value = njs_native_function(njs_date_prototype_get_utc_full_year, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getMonth"), - .value = njs_native_function(njs_date_prototype_get_month, 0, 0), + .value = njs_native_function(njs_date_prototype_get_month, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getUTCMonth"), - .value = njs_native_function(njs_date_prototype_get_utc_month, 0, 0), + .value = njs_native_function(njs_date_prototype_get_utc_month, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getDate"), - .value = njs_native_function(njs_date_prototype_get_date, 0, 0), + .value = njs_native_function(njs_date_prototype_get_date, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getUTCDate"), - .value = njs_native_function(njs_date_prototype_get_utc_date, 0, 0), + .value = njs_native_function(njs_date_prototype_get_utc_date, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getDay"), - .value = njs_native_function(njs_date_prototype_get_day, 0, 0), + .value = njs_native_function(njs_date_prototype_get_day, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getUTCDay"), - .value = njs_native_function(njs_date_prototype_get_utc_day, 0, 0), + .value = njs_native_function(njs_date_prototype_get_utc_day, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getHours"), - .value = njs_native_function(njs_date_prototype_get_hours, 0, 0), + .value = njs_native_function(njs_date_prototype_get_hours, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getUTCHours"), - .value = njs_native_function(njs_date_prototype_get_utc_hours, 0, 0), + .value = njs_native_function(njs_date_prototype_get_utc_hours, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getMinutes"), - .value = njs_native_function(njs_date_prototype_get_minutes, 0, 0), + .value = njs_native_function(njs_date_prototype_get_minutes, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getUTCMinutes"), - .value = njs_native_function(njs_date_prototype_get_utc_minutes, 0, 0), + .value = njs_native_function(njs_date_prototype_get_utc_minutes, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getSeconds"), - .value = njs_native_function(njs_date_prototype_get_seconds, 0, 0), + .value = njs_native_function(njs_date_prototype_get_seconds, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_string("getUTCSeconds"), - .value = njs_native_function(njs_date_prototype_get_seconds, 0, 0), + .value = njs_native_function(njs_date_prototype_get_seconds, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_long_string("getMilliseconds"), - .value = njs_native_function(njs_date_prototype_get_milliseconds, 0, 0), + .value = njs_native_function(njs_date_prototype_get_milliseconds, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_long_string("getUTCMilliseconds"), - .value = njs_native_function(njs_date_prototype_get_milliseconds, 0, 0), + .value = njs_native_function(njs_date_prototype_get_milliseconds, 0, + NJS_DATE_ARG), }, { .type = NJS_METHOD, .name = njs_long_string("getTimezoneOffset"), - .value = njs_native_function(njs_date_prototype_get_timezone_offset, - 0, 0), + .value = njs_native_function(njs_date_prototype_get_timezone_offset, 0, + NJS_DATE_ARG), }, { From igor at sysoev.ru Mon Oct 17 14:01:43 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 17 Oct 2016 14:01:43 +0000 Subject: [njs] Fixes in various String methods which return part of string. Message-ID: details: http://hg.nginx.org/njs/rev/938d49b0f420 branches: changeset: 202:938d49b0f420 user: Igor Sysoev date: Mon Oct 17 16:42:31 2016 +0300 description: Fixes in various String methods which return part of string. diffstat: njs/njs_array.c | 3 + njs/njs_string.c | 164 ++++++++++++++++++++++++++-------------------- njs/njs_vm.c | 16 ++-- njs/test/njs_unit_test.c | 15 ++++ 4 files changed, 118 insertions(+), 80 deletions(-) diffs (296 lines): diff -r c583e4985a7b -r 938d49b0f420 njs/njs_array.c --- a/njs/njs_array.c Fri Oct 14 18:21:37 2016 +0300 +++ b/njs/njs_array.c Mon Oct 17 16:42:31 2016 +0300 @@ -409,6 +409,9 @@ njs_array_prototype_slice(njs_vm_t *vm, start = 0; length = 0; } + + } else { + length -= start; } } } diff -r c583e4985a7b -r 938d49b0f420 njs/njs_string.c --- a/njs/njs_string.c Fri Oct 14 18:21:37 2016 +0300 +++ b/njs/njs_string.c Mon Oct 17 16:42:31 2016 +0300 @@ -886,21 +886,29 @@ njs_string_prototype_substring(njs_vm_t if (start < 0) { start = 0; + + } else if (start > length) { + start = length; } + end = length; + if (nargs > 2) { end = args[2].data.u.number; if (end < 0) { end = 0; + + } else if (end >= length) { + end = length; } - - length = end - start; - - if (length < 0) { - length = -length; - start = end; - } + } + + length = end - start; + + if (length < 0) { + length = -length; + start = end; } } @@ -920,7 +928,7 @@ static njs_ret_t njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - ssize_t start, length; + ssize_t start, length, n; njs_slice_prop_t slice; njs_string_prop_t string; @@ -931,17 +939,32 @@ njs_string_prototype_substr(njs_vm_t *vm if (nargs > 1) { start = args[1].data.u.number; - - if (start < 0) { - - start += length; + if (start < length) { + if (start < 0) { - start = 0; + start += length; + + if (start < 0) { + start = 0; + } } - } - - if (nargs > 2) { - length = args[2].data.u.number; + + length -= start; + + if (nargs > 2) { + n = args[2].data.u.number; + + if (n < 0) { + length = 0; + + } else if (n < length) { + length = n; + } + } + + } else { + start = 0; + length = 0; } } @@ -968,7 +991,8 @@ njs_string_prototype_char_at(njs_vm_t *v if (nargs > 1) { start = args[1].data.u.number; - if (start < 0) { + if (start < 0 || start >= (ssize_t) slice.string_length) { + start = 0; length = 0; } } @@ -1010,21 +1034,32 @@ njs_string_slice_args(njs_slice_prop_t * } } - end = length; - - if (nargs > 2) { - end = args[2].data.u.number; - - if (end < 0) { - end += length; - } - } - - length = end - start; - - if (length < 0) { + if (start >= length) { start = 0; length = 0; + + } else { + end = length; + + if (nargs > 2) { + end = args[2].data.u.number; + + if (end < 0) { + end += length; + } + } + + if (length >= end) { + length = end - start; + + if (length < 0) { + start = 0; + length = 0; + } + + } else { + length -= start; + } } } @@ -1038,51 +1073,36 @@ njs_string_slice(njs_vm_t *vm, njs_value const njs_string_prop_t *string, njs_slice_prop_t *slice) { size_t size, n, length; - ssize_t excess; const u_char *p, *start, *end; length = slice->length; - - if (length > 0 && slice->start < slice->string_length) { - - start = string->start; + start = string->start; + + if (string->size == slice->string_length) { + /* Byte or ASCII string. */ + start += slice->start; + size = slice->length; + + } else { + /* UTF-8 string. */ end = start + string->size; - - if (string->size == slice->string_length) { - /* Byte or ASCII string. */ - start += slice->start; - - excess = (start + length) - end; - if (excess > 0) { - length -= excess; - } - - size = length; - - if (string->length == 0) { - length = 0; - } - - } else { - /* UTF-8 string. */ - start = njs_string_offset(start, end, slice->start); - - /* Evaluate size of the slice in bytes and ajdust length. */ - p = start; - n = length; - - do { - p = nxt_utf8_next(p, end); - n--; - } while (n != 0 && p < end); - - size = p - start; - length -= n; - } - - if (nxt_fast_path(size != 0)) { - return njs_string_new(vm, &vm->retval, start, size, length); - } + start = njs_string_offset(start, end, slice->start); + + /* Evaluate size of the slice in bytes and ajdust length. */ + p = start; + n = length; + + do { + p = nxt_utf8_next(p, end); + n--; + } while (n != 0 && p < end); + + size = p - start; + length -= n; + } + + if (nxt_fast_path(size != 0)) { + return njs_string_new(vm, &vm->retval, start, size, length); } vm->retval = njs_string_empty; diff -r c583e4985a7b -r 938d49b0f420 njs/njs_vm.c --- a/njs/njs_vm.c Fri Oct 14 18:21:37 2016 +0300 +++ b/njs/njs_vm.c Mon Oct 17 16:42:31 2016 +0300 @@ -559,14 +559,14 @@ njs_vmcode_property_get(njs_vm_t *vm, nj slice.start = index; slice.length = 1; slice.string_length = njs_string_prop(&string, object); - /* - * A single codepoint string fits in vm->retval - * so the function cannot fail. - */ - (void) njs_string_slice(vm, &vm->retval, &string, &slice); - - if (nxt_fast_path(vm->retval.data.truth != 0)) { - /* Non-empty string. */ + + if (slice.start < slice.string_length) { + /* + * A single codepoint string fits in vm->retval + * so the function cannot fail. + */ + (void) njs_string_slice(vm, &vm->retval, &string, &slice); + return sizeof(njs_vmcode_prop_get_t); } } diff -r c583e4985a7b -r 938d49b0f420 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Oct 14 18:21:37 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Oct 17 16:42:31 2016 +0300 @@ -2857,6 +2857,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abcdefgh'.slice(3)"), nxt_string("defgh") }, + { nxt_string("'abcde'.slice(50)"), + nxt_string("") }, + + { nxt_string("'abcde'.slice(1, 50)"), + nxt_string("bcde") }, + { nxt_string("'abcdefgh'.slice(3, -2)"), nxt_string("def") }, @@ -2866,6 +2872,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abcdefgh'.slice(100, 120)"), nxt_string("") }, + { nxt_string("String.prototype.substring(1, 5)"), + nxt_string("") }, + + { nxt_string("String.prototype.slice(1, 5)"), + nxt_string("") }, + + { nxt_string("String.prototype.toBytes(1, 5)"), + nxt_string("") }, + { nxt_string("'abc'.charAt(1 + 1)"), nxt_string("c") }, From igor at sysoev.ru Mon Oct 17 14:03:43 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 17 Oct 2016 14:03:43 +0000 Subject: [njs] Style fixes. Message-ID: details: http://hg.nginx.org/njs/rev/6fc0e6b7f797 branches: changeset: 203:6fc0e6b7f797 user: Igor Sysoev date: Mon Oct 17 17:03:22 2016 +0300 description: Style fixes. diffstat: njs/njs_array.c | 2 ++ njs/njs_string.c | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 19 deletions(-) diffs (80 lines): diff -r 938d49b0f420 -r 6fc0e6b7f797 njs/njs_array.c --- a/njs/njs_array.c Mon Oct 17 16:42:31 2016 +0300 +++ b/njs/njs_array.c Mon Oct 17 17:03:22 2016 +0300 @@ -759,6 +759,7 @@ njs_array_prototype_join(njs_vm_t *vm, n for (i = 0; i < array->length; i++) { value = &array->start[i]; + if (!njs_is_string(value) && njs_is_valid(value) && !njs_is_null_or_void(value)) @@ -783,6 +784,7 @@ njs_array_prototype_join(njs_vm_t *vm, n for (i = 0; i < array->length; i++) { value = &array->start[i]; + if (!njs_is_string(value) && njs_is_valid(value) && !njs_is_null_or_void(value)) diff -r 938d49b0f420 -r 6fc0e6b7f797 njs/njs_string.c --- a/njs/njs_string.c Mon Oct 17 16:42:31 2016 +0300 +++ b/njs/njs_string.c Mon Oct 17 17:03:22 2016 +0300 @@ -1018,7 +1018,7 @@ static nxt_noinline void njs_string_slice_args(njs_slice_prop_t *slice, njs_value_t *args, nxt_uint_t nargs) { - ssize_t start, end, length; + ssize_t start, end, length; length = slice->string_length; start = 0; @@ -1079,30 +1079,30 @@ njs_string_slice(njs_vm_t *vm, njs_value start = string->start; if (string->size == slice->string_length) { - /* Byte or ASCII string. */ - start += slice->start; - size = slice->length; + /* Byte or ASCII string. */ + start += slice->start; + size = slice->length; } else { - /* UTF-8 string. */ + /* UTF-8 string. */ end = start + string->size; - start = njs_string_offset(start, end, slice->start); - - /* Evaluate size of the slice in bytes and ajdust length. */ - p = start; - n = length; - - do { - p = nxt_utf8_next(p, end); - n--; - } while (n != 0 && p < end); - - size = p - start; - length -= n; + start = njs_string_offset(start, end, slice->start); + + /* Evaluate size of the slice in bytes and ajdust length. */ + p = start; + n = length; + + do { + p = nxt_utf8_next(p, end); + n--; + } while (n != 0 && p < end); + + size = p - start; + length -= n; } if (nxt_fast_path(size != 0)) { - return njs_string_new(vm, &vm->retval, start, size, length); + return njs_string_new(vm, &vm->retval, start, size, length); } vm->retval = njs_string_empty; From dilaz03 at gmail.com Mon Oct 17 16:56:56 2016 From: dilaz03 at gmail.com (Dmitry Lazurkin) Date: Mon, 17 Oct 2016 19:56:56 +0300 Subject: [PATCH] Proxy: support variables for proxy_method directive Message-ID: # HG changeset patch # User Dmitry Lazurkin # Date 1476631441 -10800 # Sun Oct 16 18:24:01 2016 +0300 # Node ID b8d4a355e3ce2e47eff9424b432a22a4c86d9f08 # Parent 20eb4587225b3d7849ec5ece5732ed261226d365 Proxy: support variables for proxy_method directive. diff -r 20eb4587225b -r b8d4a355e3ce src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Fri Oct 14 19:48:26 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Sun Oct 16 18:24:01 2016 +0300 @@ -73,7 +73,7 @@ ngx_array_t *cookie_domains; ngx_array_t *cookie_paths; - ngx_str_t method; + ngx_http_complex_value_t method; ngx_str_t location; ngx_str_t url; @@ -182,6 +182,8 @@ void *conf); static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_proxy_method(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); #if (NGX_HTTP_CACHE) static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -380,9 +382,9 @@ { ngx_string("proxy_method"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_http_proxy_method, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, method), + 0, NULL }, { ngx_string("proxy_pass_request_headers"), @@ -1159,8 +1161,10 @@ /* HEAD was changed to GET to cache response */ method = u->method; - } else if (plcf->method.len) { - method = plcf->method; + } else if (plcf->method.value.data) { + if (ngx_http_complex_value(r, &plcf->method, &method) != NGX_OK) { + return NGX_ERROR; + } } else { method = r->method_name; @@ -3158,7 +3162,9 @@ #endif - ngx_conf_merge_str_value(conf->method, prev->method, ""); + if (conf->method.value.data == NULL) { + conf->method = prev->method; + } ngx_conf_merge_value(conf->upstream.pass_request_headers, prev->upstream.pass_request_headers, 1); @@ -4140,6 +4146,34 @@ } +static char * +ngx_http_proxy_method(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_proxy_loc_conf_t *plcf = conf; + + ngx_str_t *value; + ngx_http_compile_complex_value_t ccv; + + value = cf->args->elts; + + if (plcf->method.value.data) { + return "is duplicate"; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &plcf->method; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; +} + + #if (NGX_HTTP_CACHE) static char * From dilaz03 at gmail.com Mon Oct 17 17:10:03 2016 From: dilaz03 at gmail.com (Dmitry Lazurkin) Date: Mon, 17 Oct 2016 20:10:03 +0300 Subject: [PATCH] Tests: add tests for proxy_method directive Message-ID: # HG changeset patch # User Dmitry Lazurkin # Date 1476632999 -10800 # Sun Oct 16 18:49:59 2016 +0300 # Node ID b3e2d294bf908a33be87e641bbb1879aaf5e1fa2 # Parent 8c5ba361b416227d547c456ff1e4a1f6f117736b Tests: add tests for proxy_method directive. diff -r 8c5ba361b416 -r b3e2d294bf90 proxy_method.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/proxy_method.t Sun Oct 16 18:49:59 2016 +0300 @@ -0,0 +1,79 @@ +#!/usr/bin/perl + +# (C) Dmitry Lazurkin + +# Tests for proxy_method. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(3) + ->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /const { + proxy_pass http://127.0.0.1:8080/get-method; + proxy_method POST; + } + + location /var { + proxy_pass http://127.0.0.1:8080/get-method; + proxy_method $arg_method; + } + + location /parent { + proxy_method POST; + location /parent/child { + proxy_pass http://127.0.0.1:8080/get-method; + } + } + + location /get-method { + return 200 "request_method=$request_method"; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +like(http_get('/const'), qr/request_method=POST/, + 'proxy_method from constant'); + +like(http_get('/var?method=POST'), qr/request_method=POST/, + 'proxy_method from variable'); + +like(http_get('/parent/child'), qr/request_method=POST/, + 'proxy_method from parent'); + +############################################################################### From nginx at rastos.org Mon Oct 17 18:27:11 2016 From: nginx at rastos.org (Rastislav Stanik) Date: Mon, 17 Oct 2016 20:27:11 +0200 Subject: [PATCH] - flastmod SSI command In-Reply-To: <57F2A6C8.1050504@rastos.org> References: <57E2D7A5.2040304@rastos.org> <57F2A6C8.1050504@rastos.org> Message-ID: <580517FF.1040308@rastos.org> On 10/03/2016 08:43 PM, Rastislav Stanik wrote: > On 09/21/2016 08:55 PM I've sent a patch > http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008815.html > that adds support for "flastmod" SSI command. I got no feedback. I've posted a patch. I've posted the same patch again. I've asked on IRC channel and I've e-mailed Igor directly (since his name is in the history of the touched code). And I have yet to get _any_ feedback. This is getting frustrating. Is here someone who would at least tell me that nginx is not interested in my effort? Pretty please? -- thank you rastos From mdounin at mdounin.ru Mon Oct 17 18:51:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 17 Oct 2016 21:51:27 +0300 Subject: [PATCH] - flastmod SSI command In-Reply-To: <580517FF.1040308@rastos.org> References: <57E2D7A5.2040304@rastos.org> <57F2A6C8.1050504@rastos.org> <580517FF.1040308@rastos.org> Message-ID: <20161017185127.GE73038@mdounin.ru> Hello! On Mon, Oct 17, 2016 at 08:27:11PM +0200, Rastislav Stanik wrote: > On 10/03/2016 08:43 PM, Rastislav Stanik wrote: > > On 09/21/2016 08:55 PM I've sent a patch > > http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008815.html > > that adds support for "flastmod" SSI command. I got no feedback. > > I've posted a patch. I've posted the same patch again. I've asked on IRC channel > and I've e-mailed Igor directly (since his name is in the history of the touched code). > > And I have yet to get _any_ feedback. This is getting frustrating. > > Is here someone who would at least tell me that nginx is not interested in my effort? > Pretty please? The patch in question is far from being committable. And I, in particular, don't have time to do a detailed review and/or rewrite the patch. Some basic problems with the patch I see: 1. A lot of style errors. 2. It does direct file accesses, while in general SSI module doesn't access files and does subrequests instead: this allows to do arbitrary processing in URI space using nginx configuration, including passing various resources to external machines. Breaking the rule "resources used by SSI can be proxied" doesn't look like a good move, even if this is to support additional commands. Re-doing this via subrequests might be an option though. 3. The fsize command is mostly identical and should be handled in a similar manner. -- Maxim Dounin http://nginx.org/ From nginx at rastos.org Mon Oct 17 21:08:43 2016 From: nginx at rastos.org (Rastislav Stanik) Date: Mon, 17 Oct 2016 23:08:43 +0200 Subject: [PATCH] - flastmod SSI command In-Reply-To: <20161017185127.GE73038@mdounin.ru> References: <57E2D7A5.2040304@rastos.org> <57F2A6C8.1050504@rastos.org> <580517FF.1040308@rastos.org> <20161017185127.GE73038@mdounin.ru> Message-ID: <58053DDB.6070201@rastos.org> On 10/17/2016 08:51 PM, Maxim Dounin wrote: >> On 10/03/2016 08:43 PM, Rastislav Stanik wrote: >>> On 09/21/2016 08:55 PM I've sent a patch >>> http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008815.html >>> that adds support for "flastmod" SSI command. I got no feedback. > ... > The patch in question is far from being committable. And I, in > particular, don't have time to do a detailed review and/or rewrite > the patch. > > Some basic problems with the patch I see: > > 1. A lot of style errors. Hmph. > 2. It does direct file accesses, while in general SSI module > doesn't access files and does subrequests instead: this allows to > do arbitrary processing in URI space using nginx configuration, > including passing various resources to external machines. > Breaking the rule "resources used by SSI can be proxied" doesn't > look like a good move, even if this is to support additional > commands. Re-doing this via subrequests might be an option > though. I see. That moves it a bit to an unknown ground for me. I'll have a look at that. But it would be great if you could recommend someone who would find enough time to give me some guidance? > 3. The fsize command is mostly identical and should be handled in > a similar manner. I'm just trying to scratch my itch, so I did not care much about fsize. But sure, if I could get the patch for flastmod in shape good enough for you, I have no problem to add fsize too. -- bye rastos From mmskeen at gmail.com Mon Oct 17 22:21:20 2016 From: mmskeen at gmail.com (Michael Skeen) Date: Mon, 17 Oct 2016 22:21:20 +0000 Subject: nginx Architectural Patterns & Quality Attributes for Research Message-ID: <94eb2c19dc1ad4cd51053f16fee6@google.com> Hello nginx Community, I am part of an undergraduate research group focusing on software architecture patterns and quality attributes at Utah Valley University. We recently analyzed the work published on nginx in the Architecture of Open Source Applications (AOSA) and referenced it in a paper we presented at the 13th Working IEEE/IFIP Conference on Software Architecture (WICSA), as attached.? As a part of our continuing research we wish to validate our architectural analysis for nginx with the current developers. We would like to know if we are missing any patterns or quality attributes that may have been included in nginx , or if there are any we listed that aren?t used. Any additional comment on these topics you might have would also, of course, be welcome. We believe we found the following software architectural patterns in this application: Pattern Name | Is This Found in the Architecture? (yes / no / don't know) | Comments (optional) Event System Explicit Invocation Indirection Layer Layers Pipes & Filters Other? We also identified the following quality attributes: Attribute Name | Is This Found in the Architecture? | Comments (optional) Scalability Usability Extensibility Performance Maintainability Other? For your convenience, we have a complete list below of the patterns and quality attributes we referred to when conducting our research. To clarify, we are specifically studying architectural patterns, rather than design patterns such as the GoF patterns. Architectural Patterns Considered Quality Attributes Considered Active Repository Scalability Batch Usability Blackboard Extensibility Broker Performance Client Server Portability Event System Flexibility Explicit Invocation Reliability Implicit Invocation Maintainability Indirection Layer Security Interceptor Testability Interpreter Capacity Layers Cost Master and Commander Legality Microkernel Modularity Model View Controller Robustness Peer to Peer Pipes and Filters Plugin Presentation Abstraction Control Publish Subscribe Reflection Rule-Based System Shared Repository Simple Repository State Based Virtual Machine Please respond by October 25th, if possible. Thank you for considering our request, and for your continued work on nginx . Sincerely, Michael Skeen, with Erich Gubler, Danielle Skinner, Brandon Leishman, Neil Harrison, Ph.D. (advisor) Reference: Neil B. Harrison, Erich Gubler, Danielle Skinner, "Software Architecture Pattern Morphology in Open-Source Systems", WICSA , 2016, 2016 13th Working IEEE/IFIP Conference on Software Architecture (WICSA), 2016 13th Working IEEE/IFIP Conference on Software Architecture (WICSA) 2016, pp. 91-98, doi:10.1109/WICSA.2016.8 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: PID4110571 (Morphology).pdf Type: application/pdf Size: 231943 bytes Desc: not available URL: From hucong.c at foxmail.com Tue Oct 18 04:26:26 2016 From: hucong.c at foxmail.com (=?gb18030?B?uvq0zyAoaHVjYyk=?=) Date: Tue, 18 Oct 2016 12:26:26 +0800 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. Message-ID: Hi, all I've sent a patch. http://mailman.nginx.org/pipermail/nginx-devel/2016-October/008932.html that solves precision problem of ngx_http_mp4_module. Did any one noticed this patch. Downstream cache system receives duplicate data by sending start&end parameters which are analyzed from moov box and aligned with the GOP. PotPlayer becomes not fluent when playing hls stream which is converted from the mp4 (duplicate data). Nginx can not quietly change the parameter value, and send non-requested data to clients or player. So the patch is helpful. Regards, -hucc -------------- next part -------------- An HTML attachment was scrubbed... URL: From valery+nginxen at grid.net.ru Tue Oct 18 10:39:14 2016 From: valery+nginxen at grid.net.ru (Valery Kholodkov) Date: Tue, 18 Oct 2016 12:39:14 +0200 Subject: nginx Architectural Patterns & Quality Attributes for Research In-Reply-To: <94eb2c19dc1ad4cd51053f16fee6@google.com> References: <94eb2c19dc1ad4cd51053f16fee6@google.com> Message-ID: <036f2cb7-c7d2-ec7e-f18b-7c43a1c35d6f@grid.net.ru> Pardon my meticulousness, but I would dispute your observation of Explicit Invocation in favor of Implicit Invocation. Also, Virtual Machine pattern seems to be missing from your list. I also would like to share my impression of your paper: - I think you need a more substantial body of knowledge. - You accepted a common architectural pattern taxonomy, that might introduce a bias into your study. Consider coming up with a taxonomy that is more adequate to your study. Best, Val On 18-10-16 00:21, Michael Skeen wrote: > Hello nginx Community, > > > I am part of an undergraduate research group focusing on software > architecture patterns and quality attributes at Utah Valley University. > We recently analyzed the work published on nginx in the Architecture of > Open Source Applications (AOSA) and > referenced it in a paper we presented at the 13th Working IEEE/IFIP > Conference on Software Architecture (WICSA), as attached. As a part of > our continuing research we wish to validate our architectural analysis > for nginx with the current developers. > > > We would like to know if we are missing any patterns or quality > attributes that may have been included in nginx, or if there are any we > listed that aren?t used. Any additional comment on these topics you > might have would also, of course, be welcome. > > * > * > > We believe we found the following software architectural patterns in > this application: > > > *Pattern Name | Is This Found in the Architecture? (yes / no / don't > know) | Comments (optional)* > > Event System Explicit Invocation Indirection Layer Layers Pipes & Filters > > Other? > > > We also identified the following quality attributes: > > > *Attribute Name | Is This Found in the Architecture? | Comments (optional)* > > Scalability Usability Extensibility Performance Maintainability > > Other? > > > For your convenience, we have a complete list below of the patterns and > quality attributes we referred to when conducting our research. To > clarify, we are specifically studying architecturalpatterns, rather than > design patterns such as the GoF patterns. > > * > * > > Architectural Patterns Considered > > > > > Quality Attributes Considered > > Active Repository > > > > > Scalability > > Batch > > > > > Usability > > Blackboard > > > > > Extensibility > > Broker > > > > > Performance > > Client Server > > > > > Portability > > Event System > > > > > Flexibility > > Explicit Invocation > > > > > Reliability > > Implicit Invocation > > > > > Maintainability > > Indirection Layer > > > > > Security > > Interceptor > > > > > Testability > > Interpreter > > > > > Capacity > > Layers > > > > > Cost > > Master and Commander > > > > > Legality > > Microkernel > > > > > Modularity > > Model View Controller > > > > > Robustness > > Peer to Peer > > > > > Pipes and Filters > > > > > Plugin > > > > > Presentation Abstraction Control > > > > > Publish Subscribe > > > > > Reflection > > > > > Rule-Based System > > > > > Shared Repository > > > > > Simple Repository > > > > > State Based > > > > > Virtual Machine > > > > > * > * > > Please respond by October 25th, if possible. > > Thank you for considering our request, and for your continued work on nginx. > > * > * > > Sincerely, > > * > * > > Michael Skeen, with > > Erich Gubler, > > Danielle Skinner, > > Brandon Leishman, > > Neil Harrison, Ph.D. (advisor) > > > Reference: Neil B. Harrison, Erich Gubler, Danielle Skinner, "Software > Architecture Pattern Morphology in Open-Source Systems",WICSA, 2016, > 2016 13th Working IEEE/IFIP Conference on Software Architecture (WICSA), > 2016 13th Working IEEE/IFIP Conference on Software Architecture (WICSA) > 2016, pp. 91-98, doi:10.1109/WICSA.2016.8 > > > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > From igor at sysoev.ru Tue Oct 18 13:00:31 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 18 Oct 2016 13:00:31 +0000 Subject: [njs] Relative addresses have been added to disassembler output. Message-ID: details: http://hg.nginx.org/njs/rev/d055824ff0f7 branches: changeset: 204:d055824ff0f7 user: Igor Sysoev date: Mon Oct 17 23:29:15 2016 +0300 description: Relative addresses have been added to disassembler output. diffstat: njs/njs_disassembler.c | 125 +++++++++++++++++++++++++++------------------- njs/test/njs_unit_test.c | 1 + 2 files changed, 75 insertions(+), 51 deletions(-) diffs (273 lines): diff -r 6fc0e6b7f797 -r d055824ff0f7 njs/njs_disassembler.c --- a/njs/njs_disassembler.c Mon Oct 17 17:03:22 2016 +0300 +++ b/njs/njs_disassembler.c Mon Oct 17 23:29:15 2016 +0300 @@ -196,149 +196,171 @@ njs_disassemble(u_char *start, u_char *e if (operation == njs_vmcode_array) { array = (njs_vmcode_array_t *) p; - p += sizeof(njs_vmcode_array_t); - printf("ARRAY %04zX %zd\n", - (size_t) array->retval, (size_t) array->length); + printf("%05zd ARRAY %04zX %zd\n", + p - start, (size_t) array->retval, (size_t) array->length); + + p += sizeof(njs_vmcode_array_t); continue; } if (operation == njs_vmcode_if_true_jump) { cond_jump = (njs_vmcode_cond_jump_t *) p; - p += sizeof(njs_vmcode_cond_jump_t); sign = (cond_jump->offset >= 0) ? "+" : ""; - printf("JUMP IF TRUE %04zX %s%zd\n", - (size_t) cond_jump->cond, sign, (size_t) cond_jump->offset); + printf("%05zd JUMP IF TRUE %04zX %s%zd\n", + p - start, (size_t) cond_jump->cond, sign, + (size_t) cond_jump->offset); + + p += sizeof(njs_vmcode_cond_jump_t); continue; } if (operation == njs_vmcode_if_false_jump) { cond_jump = (njs_vmcode_cond_jump_t *) p; - p += sizeof(njs_vmcode_cond_jump_t); sign = (cond_jump->offset >= 0) ? "+" : ""; - printf("JUMP IF FALSE %04zX %s%zd\n", - (size_t) cond_jump->cond, sign, (size_t) cond_jump->offset); + printf("%05zd JUMP IF FALSE %04zX %s%zd\n", + p - start, (size_t) cond_jump->cond, sign, + (size_t) cond_jump->offset); + + p += sizeof(njs_vmcode_cond_jump_t); continue; } if (operation == njs_vmcode_jump) { jump = (njs_vmcode_jump_t *) p; - p += sizeof(njs_vmcode_jump_t); sign = (jump->offset >= 0) ? "+" : ""; - printf("JUMP %s%zd\n", sign, (size_t) jump->offset); + printf("%05zd JUMP %s%zd\n", + p - start, sign, (size_t) jump->offset); + + p += sizeof(njs_vmcode_jump_t); continue; } if (operation == njs_vmcode_if_equal_jump) { equal = (njs_vmcode_equal_jump_t *) p; - p += sizeof(njs_vmcode_equal_jump_t); - printf("JUMP IF EQUAL %04zX %04zX +%zd\n", - (size_t) equal->value1, (size_t) equal->value2, + printf("%05zd JUMP IF EQUAL %04zX %04zX +%zd\n", + p - start, (size_t) equal->value1, (size_t) equal->value2, (size_t) equal->offset); + p += sizeof(njs_vmcode_equal_jump_t); + continue; } if (operation == njs_vmcode_test_if_true) { test_jump = (njs_vmcode_test_jump_t *) p; - p += sizeof(njs_vmcode_test_jump_t); - printf("TEST IF TRUE %04zX %04zX +%zd\n", - (size_t) test_jump->retval, (size_t) test_jump->value, - (size_t) test_jump->offset); + printf("%05zd TEST IF TRUE %04zX %04zX +%zd\n", + p - start, (size_t) test_jump->retval, + (size_t) test_jump->value, (size_t) test_jump->offset); + + p += sizeof(njs_vmcode_test_jump_t); continue; } if (operation == njs_vmcode_test_if_false) { test_jump = (njs_vmcode_test_jump_t *) p; - p += sizeof(njs_vmcode_test_jump_t); - printf("TEST IF FALSE %04zX %04zX +%zd\n", - (size_t) test_jump->retval, (size_t) test_jump->value, - (size_t) test_jump->offset); + printf("%05zd TEST IF FALSE %04zX %04zX +%zd\n", + p - start, (size_t) test_jump->retval, + (size_t) test_jump->value, (size_t) test_jump->offset); + + p += sizeof(njs_vmcode_test_jump_t); continue; } if (operation == njs_vmcode_function_frame) { function = (njs_vmcode_function_frame_t *) p; - p += sizeof(njs_vmcode_function_frame_t); - printf("FUNCTION FRAME %04zX %zd%s\n", - (size_t) function->name, function->nargs, + printf("%05zd FUNCTION FRAME %04zX %zd%s\n", + p - start, (size_t) function->name, function->nargs, function->code.ctor ? " CTOR" : ""); + p += sizeof(njs_vmcode_function_frame_t); + continue; } if (operation == njs_vmcode_method_frame) { method = (njs_vmcode_method_frame_t *) p; - p += sizeof(njs_vmcode_method_frame_t); - printf("METHOD FRAME %04zX %04zX %zd%s\n", - (size_t) method->object, (size_t) method->method, + printf("%05zd METHOD FRAME %04zX %04zX %zd%s\n", + p - start, (size_t) method->object, (size_t) method->method, method->nargs, method->code.ctor ? " CTOR" : ""); + + p += sizeof(njs_vmcode_method_frame_t); continue; } if (operation == njs_vmcode_property_foreach) { prop_foreach = (njs_vmcode_prop_foreach_t *) p; - p += sizeof(njs_vmcode_prop_foreach_t); - printf("PROPERTY FOREACH %04zX %04zX +%zd\n", - (size_t) prop_foreach->next, (size_t) prop_foreach->object, + printf("%05zd PROPERTY FOREACH %04zX %04zX +%zd\n", + p - start, (size_t) prop_foreach->next, + (size_t) prop_foreach->object, (size_t) prop_foreach->offset); + + p += sizeof(njs_vmcode_prop_foreach_t); continue; } if (operation == njs_vmcode_property_next) { prop_next = (njs_vmcode_prop_next_t *) p; - p += sizeof(njs_vmcode_prop_next_t); - printf("PROPERTY NEXT %04zX %04zX %04zX %zd\n", - (size_t) prop_next->retval, (size_t) prop_next->object, - (size_t) prop_next->next, (size_t) prop_next->offset); + printf("%05zd PROPERTY NEXT %04zX %04zX %04zX %zd\n", + p - start, (size_t) prop_next->retval, + (size_t) prop_next->object, (size_t) prop_next->next, + (size_t) prop_next->offset); + + p += sizeof(njs_vmcode_prop_next_t); continue; } if (operation == njs_vmcode_try_start) { try_start = (njs_vmcode_try_start_t *) p; - p += sizeof(njs_vmcode_try_start_t); - printf("TRY START %04zX +%zd\n", - (size_t) try_start->value, (size_t) try_start->offset); + printf("%05zd TRY START %04zX +%zd\n", + p - start, (size_t) try_start->value, + (size_t) try_start->offset); + + p += sizeof(njs_vmcode_try_start_t); continue; } if (operation == njs_vmcode_catch) { catch = (njs_vmcode_catch_t *) p; - p += sizeof(njs_vmcode_catch_t); - printf("CATCH %04zX +%zd\n", - (size_t) catch->exception, (size_t) catch->offset); + printf("%05zd CATCH %04zX +%zd\n", + p - start, (size_t) catch->exception, + (size_t) catch->offset); + + p += sizeof(njs_vmcode_catch_t); continue; } if (operation == njs_vmcode_try_end) { try_end = (njs_vmcode_try_end_t *) p; + + printf("%05zd TRY END +%zd\n", + p - start, (size_t) try_end->offset); + p += sizeof(njs_vmcode_try_end_t); - printf("TRY END +%zd\n", (size_t) try_end->offset); - continue; } @@ -352,23 +374,23 @@ njs_disassemble(u_char *start, u_char *e if (code_name->size == sizeof(njs_vmcode_3addr_t)) { code3 = (njs_vmcode_3addr_t *) p; - printf("%*s %04zX %04zX %04zX\n", - (int) name->length, name->start, + printf("%05zd %*s %04zX %04zX %04zX\n", + p - start, (int) name->length, name->start, (size_t) code3->dst, (size_t) code3->src1, (size_t) code3->src2); } else if (code_name->size == sizeof(njs_vmcode_2addr_t)) { code2 = (njs_vmcode_2addr_t *) p; - printf("%*s %04zX %04zX\n", - (int) name->length, name->start, + printf("%05zd %*s %04zX %04zX\n", + p - start, (int) name->length, name->start, (size_t) code2->dst, (size_t) code2->src); } else if (code_name->size == sizeof(njs_vmcode_1addr_t)) { code1 = (njs_vmcode_1addr_t *) p; - printf("%*s %04zX\n", - (int) name->length, name->start, + printf("%05zd %*s %04zX\n", + p - start, (int) name->length, name->start, (size_t) code1->index); } @@ -382,10 +404,11 @@ njs_disassemble(u_char *start, u_char *e } while (n != 0); + printf("%05zd UNKNOWN %04zX\n", + p - start, (size_t) (uintptr_t) operation); + p += sizeof(njs_vmcode_operation_t); - printf("UNKNOWN %04zX\n", (size_t) (uintptr_t) operation); - next: continue; diff -r 6fc0e6b7f797 -r d055824ff0f7 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 17 17:03:22 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Oct 17 23:29:15 2016 +0300 @@ -5602,6 +5602,7 @@ njs_unit_test(nxt_bool_t disassemble) if (ret == NXT_OK) { if (disassemble) { njs_disassembler(vm); + fflush(stdout); } nvm = njs_vm_clone(vm, NULL, &ext_object); From igor at sysoev.ru Tue Oct 18 13:00:38 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 18 Oct 2016 13:00:38 +0000 Subject: [njs] Fixes in generating "continue" and "break" statements. Message-ID: details: http://hg.nginx.org/njs/rev/462f7d2113f9 branches: changeset: 205:462f7d2113f9 user: Igor Sysoev date: Tue Oct 18 15:48:13 2016 +0300 description: Fixes in generating "continue" and "break" statements. diffstat: njs/njs_generator.c | 8 ++++---- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diffs (38 lines): diff -r d055824ff0f7 -r 462f7d2113f9 njs/njs_generator.c --- a/njs/njs_generator.c Mon Oct 17 23:29:15 2016 +0300 +++ b/njs/njs_generator.c Tue Oct 18 15:48:13 2016 +0300 @@ -1089,8 +1089,8 @@ found: patch = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_parser_patch_t)); if (nxt_fast_path(patch != NULL)) { - patch->next = parser->block->continuation; - parser->block->continuation = patch; + patch->next = block->continuation; + block->continuation = patch; njs_generate_code(parser, njs_vmcode_jump_t, jump); jump->code.operation = njs_vmcode_jump; @@ -1133,8 +1133,8 @@ found: patch = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_parser_patch_t)); if (nxt_fast_path(patch != NULL)) { - patch->next = parser->block->exit; - parser->block->exit = patch; + patch->next = block->exit; + block->exit = patch; njs_generate_code(parser, njs_vmcode_jump_t, jump); jump->code.operation = njs_vmcode_jump; diff -r d055824ff0f7 -r 462f7d2113f9 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 17 23:29:15 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 18 15:48:13 2016 +0300 @@ -1657,6 +1657,9 @@ static njs_unit_test_t njs_test[] = "for (i in a) { if (a[i] > 4) continue; s += a[i] } s"), nxt_string("10") }, + { nxt_string("var a; for (a = 1; a; a--) switch (a) { case 0: continue }"), + nxt_string("undefined") }, + /* break. */ { nxt_string("break"), From igor at sysoev.ru Tue Oct 18 13:00:39 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 18 Oct 2016 13:00:39 +0000 Subject: [njs] A fix of function name usage. Message-ID: details: http://hg.nginx.org/njs/rev/b2a23cf748f8 branches: changeset: 206:b2a23cf748f8 user: Igor Sysoev date: Tue Oct 18 15:48:19 2016 +0300 description: A fix of function name usage. diffstat: njs/njs_generator.c | 9 ++------- njs/njs_parser.c | 1 + njs/njs_variable.h | 3 ++- 3 files changed, 5 insertions(+), 8 deletions(-) diffs (52 lines): diff -r 462f7d2113f9 -r b2a23cf748f8 njs/njs_generator.c --- a/njs/njs_generator.c Tue Oct 18 15:48:13 2016 +0300 +++ b/njs/njs_generator.c Tue Oct 18 15:48:19 2016 +0300 @@ -333,14 +333,9 @@ njs_generator(njs_vm_t *vm, njs_parser_t static nxt_int_t njs_generate_name(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node) { - njs_index_t index; - njs_value_t *value; njs_vmcode_object_copy_t *copy; - index = node->u.variable->index; - value = njs_variable_value(parser, index); - - if (value->type == NJS_FUNCTION) { + if (node->u.variable->function) { node->index = njs_generator_dest_index(vm, parser, node); if (nxt_slow_path(node->index == NJS_INDEX_ERROR)) { @@ -352,7 +347,7 @@ njs_generate_name(njs_vm_t *vm, njs_pars copy->code.operands = NJS_VMCODE_2OPERANDS; copy->code.retval = NJS_VMCODE_RETVAL; copy->retval = node->index; - copy->object = index; + copy->object = node->u.variable->index; return NXT_OK; } diff -r 462f7d2113f9 -r b2a23cf748f8 njs/njs_parser.c --- a/njs/njs_parser.c Tue Oct 18 15:48:13 2016 +0300 +++ b/njs/njs_parser.c Tue Oct 18 15:48:19 2016 +0300 @@ -315,6 +315,7 @@ njs_parser_function_declaration(njs_vm_t } var->state = NJS_VARIABLE_DECLARED; + var->function = 1; node->index = var->index; token = njs_parser_token(parser); diff -r 462f7d2113f9 -r b2a23cf748f8 njs/njs_variable.h --- a/njs/njs_variable.h Tue Oct 18 15:48:13 2016 +0300 +++ b/njs/njs_variable.h Tue Oct 18 15:48:19 2016 +0300 @@ -20,7 +20,8 @@ typedef enum { typedef struct { u_char *name_start; uint16_t name_len; - njs_variable_state_t state:8; /* 3 bits */ + njs_variable_state_t state:8; /* 3 bits */ + uint8_t function; /* 1 bit */ njs_index_t index; } njs_variable_t; From igor at sysoev.ru Tue Oct 18 13:00:40 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 18 Oct 2016 13:00:40 +0000 Subject: [njs] Invalid Unicode code point processing has been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/59b3b4a0b535 branches: changeset: 207:59b3b4a0b535 user: Igor Sysoev date: Tue Oct 18 15:48:22 2016 +0300 description: Invalid Unicode code point processing has been fixed. diffstat: njs/njs_parser.c | 3 +++ njs/test/njs_unit_test.c | 3 +++ 2 files changed, 6 insertions(+), 0 deletions(-) diffs (26 lines): diff -r b2a23cf748f8 -r 59b3b4a0b535 njs/njs_parser.c --- a/njs/njs_parser.c Tue Oct 18 15:48:19 2016 +0300 +++ b/njs/njs_parser.c Tue Oct 18 15:48:22 2016 +0300 @@ -2135,6 +2135,9 @@ njs_parser_escape_string_create(njs_vm_t if (dst != NULL) { dst = nxt_utf8_encode(dst, (uint32_t) u); + if (dst == NULL) { + goto invalid; + } } } diff -r b2a23cf748f8 -r 59b3b4a0b535 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 18 15:48:19 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 18 15:48:22 2016 +0300 @@ -2660,6 +2660,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("'\\u{1234567}'"), nxt_string("SyntaxError: Invalid Unicode code point \"\\u{1234567}\" in 1") }, + { nxt_string("'\\u{a00000}'"), + nxt_string("SyntaxError: Invalid Unicode code point \"\\u{a00000}\" in 1") }, + { nxt_string("'\\x61'"), nxt_string("a") }, From mdounin at mdounin.ru Tue Oct 18 14:47:47 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:47:47 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/d4e6c9d8c56b branches: stable-1.10 changeset: 6748:d4e6c9d8c56b user: Maxim Dounin date: Tue Oct 18 17:19:51 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 1010001 -#define NGINX_VERSION "1.10.1" +#define nginx_version 1010002 +#define NGINX_VERSION "1.10.2" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From mdounin at mdounin.ru Tue Oct 18 14:47:50 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:47:50 +0000 Subject: [nginx] HTTP/2: the "421 Misdirected Request" response (closes #848). Message-ID: details: http://hg.nginx.org/nginx/rev/f88a145b093e branches: stable-1.10 changeset: 6749:f88a145b093e user: Valentin Bartenev date: Fri May 20 18:41:17 2016 +0300 description: HTTP/2: the "421 Misdirected Request" response (closes #848). Since 4fbef397c753 nginx rejects with the 400 error any attempts of requesting different host over the same connection, if the relevant virtual server requires verification of a client certificate. While requesting hosts other than negotiated isn't something legal in HTTP/1.x, the HTTP/2 specification explicitly permits such requests for connection reuse and has introduced a special response code 421. According to RFC 7540 Section 9.1.2 this code can be sent by a server that is not configured to produce responses for the combination of scheme and authority that are included in the request URI. And the client may retry the request over a different connection. Now this code is used for requests that aren't authorized in current connection. After receiving the 421 response a client will be able to open a new connection, provide the required certificate and retry the request. Unfortunately, not all clients currently are able to handle it well. Notably Chrome just shows an error, while at least the latest version of Firefox retries the request over a new connection. diffstat: src/http/ngx_http_header_filter_module.c | 14 +++++++------- src/http/ngx_http_request.c | 2 +- src/http/ngx_http_request.h | 1 + src/http/ngx_http_special_response.c | 15 ++++++++++++++- 4 files changed, 23 insertions(+), 9 deletions(-) diffs (95 lines): diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -95,17 +95,17 @@ static ngx_str_t ngx_http_status_lines[] ngx_string("414 Request-URI Too Large"), ngx_string("415 Unsupported Media Type"), ngx_string("416 Requested Range Not Satisfiable"), + ngx_null_string, /* "417 Expectation Failed" */ + ngx_null_string, /* "418 unused" */ + ngx_null_string, /* "419 unused" */ + ngx_null_string, /* "420 unused" */ + ngx_string("421 Misdirected Request"), - /* ngx_null_string, */ /* "417 Expectation Failed" */ - /* ngx_null_string, */ /* "418 unused" */ - /* ngx_null_string, */ /* "419 unused" */ - /* ngx_null_string, */ /* "420 unused" */ - /* ngx_null_string, */ /* "421 unused" */ /* ngx_null_string, */ /* "422 Unprocessable Entity" */ /* ngx_null_string, */ /* "423 Locked" */ /* ngx_null_string, */ /* "424 Failed Dependency" */ -#define NGX_HTTP_LAST_4XX 417 +#define NGX_HTTP_LAST_4XX 422 #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string("500 Internal Server Error"), @@ -113,10 +113,10 @@ static ngx_str_t ngx_http_status_lines[] ngx_string("502 Bad Gateway"), ngx_string("503 Service Temporarily Unavailable"), ngx_string("504 Gateway Time-out"), - ngx_null_string, /* "505 HTTP Version Not Supported" */ ngx_null_string, /* "506 Variant Also Negotiates" */ ngx_string("507 Insufficient Storage"), + /* ngx_null_string, */ /* "508 unused" */ /* ngx_null_string, */ /* "509 unused" */ /* ngx_null_string, */ /* "510 Not Extended" */ diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -2065,7 +2065,7 @@ ngx_http_set_virtual_server(ngx_http_req ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client attempted to request the server name " "different from that one was negotiated"); - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST); return NGX_ERROR; } } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -95,6 +95,7 @@ #define NGX_HTTP_REQUEST_URI_TOO_LARGE 414 #define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE 415 #define NGX_HTTP_RANGE_NOT_SATISFIABLE 416 +#define NGX_HTTP_MISDIRECTED_REQUEST 421 /* Our own HTTP codes */ diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -210,6 +210,14 @@ static char ngx_http_error_416_page[] = ; +static char ngx_http_error_421_page[] = +"" CRLF +"421 Misdirected Request" CRLF +"" CRLF +"

421 Misdirected Request

" CRLF +; + + static char ngx_http_error_494_page[] = "" CRLF "400 Request Header Or Cookie Too Large" @@ -334,8 +342,13 @@ static ngx_str_t ngx_http_error_pages[] ngx_string(ngx_http_error_414_page), ngx_string(ngx_http_error_415_page), ngx_string(ngx_http_error_416_page), + ngx_null_string, /* 417 */ + ngx_null_string, /* 418 */ + ngx_null_string, /* 419 */ + ngx_null_string, /* 420 */ + ngx_string(ngx_http_error_421_page), -#define NGX_HTTP_LAST_4XX 417 +#define NGX_HTTP_LAST_4XX 422 #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 */ From mdounin at mdounin.ru Tue Oct 18 14:47:53 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:47:53 +0000 Subject: [nginx] HTTP/2: implemented preread buffer for request body (closes #959). Message-ID: details: http://hg.nginx.org/nginx/rev/cb330cd39030 branches: stable-1.10 changeset: 6750:cb330cd39030 user: Valentin Bartenev date: Tue May 24 17:37:52 2016 +0300 description: HTTP/2: implemented preread buffer for request body (closes #959). Previously, the stream's window was kept zero in order to prevent a client from sending the request body before it was requested (see 887cca40ba6a for details). Until such initial window was acknowledged all requests with data were rejected (see 0aa07850922f for details). That approach revealed a number of problems: 1. Some clients (notably MS IE/Edge, Safari, iOS applications) show an error or even crash if a stream is rejected; 2. This requires at least one RTT for every request with body before the client receives window update and able to send data. To overcome these problems the new directive "http2_body_preread_size" is introduced. It sets the initial window and configures a special per stream preread buffer that is used to save all incoming data before the body is requested and processed. If the directive's value is lower than the default initial window (65535), as previously, all streams with data will be rejected until the new window is acknowledged. Otherwise, no special processing is used and all requests with data are welcome right from the connection start. The default value is chosen to be 64k, which is bigger than the default initial window. Setting it to zero is fully complaint to the previous behavior. diffstat: src/http/v2/ngx_http_v2.c | 168 +++++++++++++++++++++++++++----------- src/http/v2/ngx_http_v2.h | 5 + src/http/v2/ngx_http_v2_module.c | 31 +++++++ src/http/v2/ngx_http_v2_module.h | 1 + 4 files changed, 154 insertions(+), 51 deletions(-) diffs (400 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -48,11 +48,6 @@ #define NGX_HTTP_V2_DEFAULT_FRAME_SIZE (1 << 14) -#define NGX_HTTP_V2_MAX_WINDOW ((1U << 31) - 1) -#define NGX_HTTP_V2_DEFAULT_WINDOW 65535 - -#define NGX_HTTP_V2_INITIAL_WINDOW 0 - #define NGX_HTTP_V2_ROOT (void *) -1 @@ -879,8 +874,6 @@ ngx_http_v2_state_data(ngx_http_v2_conne return ngx_http_v2_state_skip_padded(h2c, pos, end); } - stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; - h2c->state.stream = stream; return ngx_http_v2_state_read_data(h2c, pos, end); @@ -891,10 +884,12 @@ static u_char * ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { - size_t size; - ngx_int_t rc; - ngx_uint_t last; - ngx_http_v2_stream_t *stream; + size_t size; + ngx_buf_t *buf; + ngx_int_t rc; + ngx_http_request_t *r; + ngx_http_v2_stream_t *stream; + ngx_http_v2_srv_conf_t *h2scf; stream = h2c->state.stream; @@ -913,17 +908,42 @@ ngx_http_v2_state_read_data(ngx_http_v2_ if (size >= h2c->state.length) { size = h2c->state.length; - last = stream->in_closed; - - } else { - last = 0; - } - - rc = ngx_http_v2_process_request_body(stream->request, pos, size, last); - - if (rc != NGX_OK) { - stream->skip_data = 1; - ngx_http_finalize_request(stream->request, rc); + stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; + } + + r = stream->request; + + if (r->request_body) { + rc = ngx_http_v2_process_request_body(r, pos, size, stream->in_closed); + + if (rc != NGX_OK) { + stream->skip_data = 1; + ngx_http_finalize_request(r, rc); + } + + } else if (size) { + buf = stream->preread; + + if (buf == NULL) { + h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module); + + buf = ngx_create_temp_buf(r->pool, h2scf->preread_size); + if (buf == NULL) { + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + + stream->preread = buf; + } + + if (size > (size_t) (buf->end - buf->last)) { + ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0, + "http2 preread buffer overflow"); + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + + buf->last = ngx_cpymem(buf->last, pos, size); } pos += size; @@ -1058,7 +1078,9 @@ ngx_http_v2_state_headers(ngx_http_v2_co goto rst_stream; } - if (!h2c->settings_ack && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)) + if (!h2c->settings_ack + && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG) + && h2scf->preread_size < NGX_HTTP_V2_DEFAULT_WINDOW) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client sent stream with data " @@ -2434,8 +2456,7 @@ ngx_http_v2_send_settings(ngx_http_v2_co buf->last = ngx_http_v2_write_uint16(buf->last, NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING); - buf->last = ngx_http_v2_write_uint32(buf->last, - NGX_HTTP_V2_INITIAL_WINDOW); + buf->last = ngx_http_v2_write_uint32(buf->last, h2scf->preread_size); buf->last = ngx_http_v2_write_uint16(buf->last, NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING); @@ -2643,6 +2664,7 @@ ngx_http_v2_create_stream(ngx_http_v2_co ngx_http_log_ctx_t *ctx; ngx_http_request_t *r; ngx_http_v2_stream_t *stream; + ngx_http_v2_srv_conf_t *h2scf; ngx_http_core_srv_conf_t *cscf; fc = h2c->free_fake_connections; @@ -2756,8 +2778,10 @@ ngx_http_v2_create_stream(ngx_http_v2_co stream->request = r; stream->connection = h2c; + h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module); + stream->send_window = h2c->init_window; - stream->recv_window = NGX_HTTP_V2_INITIAL_WINDOW; + stream->recv_window = h2scf->preread_size; h2c->processing++; @@ -3411,7 +3435,11 @@ ngx_http_v2_read_request_body(ngx_http_r ngx_http_client_body_handler_pt post_handler) { off_t len; + size_t size; + ngx_buf_t *buf; + ngx_int_t rc; ngx_http_v2_stream_t *stream; + ngx_http_v2_srv_conf_t *h2scf; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; ngx_http_v2_connection_t *h2c; @@ -3444,24 +3472,34 @@ ngx_http_v2_read_request_body(ngx_http_r r->request_body = rb; + h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); len = r->headers_in.content_length_n; if (r->request_body_no_buffering && !stream->in_closed) { - r->request_body_in_file_only = 0; if (len < 0 || len > (off_t) clcf->client_body_buffer_size) { len = clcf->client_body_buffer_size; } + /* + * We need a room to store data up to the stream's initial window size, + * at least until this window will be exhausted. + */ + + if (len < (off_t) h2scf->preread_size) { + len = h2scf->preread_size; + } + if (len > NGX_HTTP_V2_MAX_WINDOW) { len = NGX_HTTP_V2_MAX_WINDOW; } - } - - if (len >= 0 && len <= (off_t) clcf->client_body_buffer_size - && !r->request_body_in_file_only) + + rb->buf = ngx_create_temp_buf(r->pool, (size_t) len); + + } else if (len >= 0 && len <= (off_t) clcf->client_body_buffer_size + && !r->request_body_in_file_only) { rb->buf = ngx_create_temp_buf(r->pool, (size_t) len); @@ -3478,22 +3516,44 @@ ngx_http_v2_read_request_body(ngx_http_r return NGX_HTTP_INTERNAL_SERVER_ERROR; } + buf = stream->preread; + if (stream->in_closed) { r->request_body_no_buffering = 0; + + if (buf) { + rc = ngx_http_v2_process_request_body(r, buf->pos, + buf->last - buf->pos, 1); + ngx_pfree(r->pool, buf->start); + return rc; + } + return ngx_http_v2_process_request_body(r, NULL, 0, 1); } - if (len) { - if (r->request_body_no_buffering) { - stream->recv_window = (size_t) len; - - } else { - stream->no_flow_control = 1; - stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + if (buf) { + rc = ngx_http_v2_process_request_body(r, buf->pos, + buf->last - buf->pos, 0); + + ngx_pfree(r->pool, buf->start); + + if (rc != NGX_OK) { + stream->skip_data = 1; + return rc; } - - if (ngx_http_v2_send_window_update(stream->connection, stream->node->id, - stream->recv_window) + } + + if (r->request_body_no_buffering) { + size = len - h2scf->preread_size; + + } else { + stream->no_flow_control = 1; + size = NGX_HTTP_V2_MAX_WINDOW - stream->recv_window; + } + + if (size) { + if (ngx_http_v2_send_window_update(stream->connection, + stream->node->id, size) == NGX_ERROR) { stream->skip_data = 1; @@ -3508,9 +3568,13 @@ ngx_http_v2_read_request_body(ngx_http_r return NGX_HTTP_INTERNAL_SERVER_ERROR; } } - } - - ngx_add_timer(r->connection->read, clcf->client_body_timeout); + + stream->recv_window += size; + } + + if (!buf) { + ngx_add_timer(r->connection->read, clcf->client_body_timeout); + } r->read_event_handler = ngx_http_v2_read_client_request_body_handler; r->write_event_handler = ngx_http_request_empty_handler; @@ -3529,13 +3593,8 @@ ngx_http_v2_process_request_body(ngx_htt ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; + fc = r->connection; rb = r->request_body; - - if (rb == NULL) { - return NGX_OK; - } - - fc = r->connection; buf = rb->buf; if (size) { @@ -3789,7 +3848,14 @@ ngx_http_v2_read_unbuffered_request_body window -= h2c->state.length; } - if (window == stream->recv_window) { + if (window <= stream->recv_window) { + if (window < stream->recv_window) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "http2 negative window update"); + stream->skip_data = 1; + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + return NGX_AGAIN; } diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h +++ b/src/http/v2/ngx_http_v2.h @@ -46,6 +46,9 @@ #define NGX_HTTP_V2_PADDED_FLAG 0x08 #define NGX_HTTP_V2_PRIORITY_FLAG 0x20 +#define NGX_HTTP_V2_MAX_WINDOW ((1U << 31) - 1) +#define NGX_HTTP_V2_DEFAULT_WINDOW 65535 + typedef struct ngx_http_v2_connection_s ngx_http_v2_connection_t; typedef struct ngx_http_v2_node_s ngx_http_v2_node_t; @@ -174,6 +177,8 @@ struct ngx_http_v2_stream_s { ssize_t send_window; size_t recv_window; + ngx_buf_t *preread; + ngx_http_v2_out_frame_t *free_frames; ngx_chain_t *free_frame_headers; ngx_chain_t *free_bufs; diff --git a/src/http/v2/ngx_http_v2_module.c b/src/http/v2/ngx_http_v2_module.c --- a/src/http/v2/ngx_http_v2_module.c +++ b/src/http/v2/ngx_http_v2_module.c @@ -30,6 +30,7 @@ static char *ngx_http_v2_merge_loc_conf( static char *ngx_http_v2_recv_buffer_size(ngx_conf_t *cf, void *post, void *data); static char *ngx_http_v2_pool_size(ngx_conf_t *cf, void *post, void *data); +static char *ngx_http_v2_preread_size(ngx_conf_t *cf, void *post, void *data); static char *ngx_http_v2_streams_index_mask(ngx_conf_t *cf, void *post, void *data); static char *ngx_http_v2_chunk_size(ngx_conf_t *cf, void *post, void *data); @@ -41,6 +42,8 @@ static ngx_conf_post_t ngx_http_v2_recv { ngx_http_v2_recv_buffer_size }; static ngx_conf_post_t ngx_http_v2_pool_size_post = { ngx_http_v2_pool_size }; +static ngx_conf_post_t ngx_http_v2_preread_size_post = + { ngx_http_v2_preread_size }; static ngx_conf_post_t ngx_http_v2_streams_index_mask_post = { ngx_http_v2_streams_index_mask }; static ngx_conf_post_t ngx_http_v2_chunk_size_post = @@ -84,6 +87,13 @@ static ngx_command_t ngx_http_v2_comman offsetof(ngx_http_v2_srv_conf_t, max_header_size), NULL }, + { ngx_string("http2_body_preread_size"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_v2_srv_conf_t, preread_size), + &ngx_http_v2_preread_size_post }, + { ngx_string("http2_streams_index_size"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, @@ -316,6 +326,8 @@ ngx_http_v2_create_srv_conf(ngx_conf_t * h2scf->max_field_size = NGX_CONF_UNSET_SIZE; h2scf->max_header_size = NGX_CONF_UNSET_SIZE; + h2scf->preread_size = NGX_CONF_UNSET_SIZE; + h2scf->streams_index_mask = NGX_CONF_UNSET_UINT; h2scf->recv_timeout = NGX_CONF_UNSET_MSEC; @@ -341,6 +353,8 @@ ngx_http_v2_merge_srv_conf(ngx_conf_t *c ngx_conf_merge_size_value(conf->max_header_size, prev->max_header_size, 16384); + ngx_conf_merge_size_value(conf->preread_size, prev->preread_size, 65536); + ngx_conf_merge_uint_value(conf->streams_index_mask, prev->streams_index_mask, 32 - 1); @@ -420,6 +434,23 @@ ngx_http_v2_pool_size(ngx_conf_t *cf, vo static char * +ngx_http_v2_preread_size(ngx_conf_t *cf, void *post, void *data) +{ + size_t *sp = data; + + if (*sp > NGX_HTTP_V2_MAX_WINDOW) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the maximum body preread buffer size is %uz", + NGX_HTTP_V2_MAX_WINDOW); + + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; +} + + +static char * ngx_http_v2_streams_index_mask(ngx_conf_t *cf, void *post, void *data) { ngx_uint_t *np = data; diff --git a/src/http/v2/ngx_http_v2_module.h b/src/http/v2/ngx_http_v2_module.h --- a/src/http/v2/ngx_http_v2_module.h +++ b/src/http/v2/ngx_http_v2_module.h @@ -25,6 +25,7 @@ typedef struct { ngx_uint_t concurrent_streams; size_t max_field_size; size_t max_header_size; + size_t preread_size; ngx_uint_t streams_index_mask; ngx_msec_t recv_timeout; ngx_msec_t idle_timeout; From mdounin at mdounin.ru Tue Oct 18 14:47:56 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:47:56 +0000 Subject: [nginx] HTTP/2: unbreak build on MSVC. Message-ID: details: http://hg.nginx.org/nginx/rev/696dbfb0490a branches: stable-1.10 changeset: 6751:696dbfb0490a user: Valentin Bartenev date: Tue May 24 21:54:32 2016 +0300 description: HTTP/2: unbreak build on MSVC. diffstat: src/http/v2/ngx_http_v2.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -3544,7 +3544,7 @@ ngx_http_v2_read_request_body(ngx_http_r } if (r->request_body_no_buffering) { - size = len - h2scf->preread_size; + size = (size_t) len - h2scf->preread_size; } else { stream->no_flow_control = 1; From mdounin at mdounin.ru Tue Oct 18 14:47:58 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:47:58 +0000 Subject: [nginx] HTTP/2: fixed a segfault while processing unbuffered upload. Message-ID: details: http://hg.nginx.org/nginx/rev/0708285115fa branches: stable-1.10 changeset: 6752:0708285115fa user: Valentin Bartenev date: Thu Jun 16 20:55:11 2016 +0300 description: HTTP/2: fixed a segfault while processing unbuffered upload. The ngx_http_v2_finalize_connection() closes current stream, but that is an invalid operation while processing unbuffered upload. This results in access to already freed memory, since the upstream module sets a cleanup handler that also finalizes the request. diffstat: src/http/v2/ngx_http_v2.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diffs (14 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -4169,10 +4169,6 @@ ngx_http_v2_finalize_connection(ngx_http c->error = 1; - if (h2c->state.stream) { - ngx_http_v2_close_stream(h2c->state.stream, NGX_HTTP_BAD_REQUEST); - } - if (!h2c->processing) { ngx_http_close_connection(c); return; From mdounin at mdounin.ru Tue Oct 18 14:48:00 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:00 +0000 Subject: [nginx] HTTP/2: prevented double termination of a stream. Message-ID: details: http://hg.nginx.org/nginx/rev/20485a482bc0 branches: stable-1.10 changeset: 6753:20485a482bc0 user: Valentin Bartenev date: Thu Jun 16 20:55:11 2016 +0300 description: HTTP/2: prevented double termination of a stream. According to RFC 7540, an endpoint should not send more than one RST_STREAM frame for any stream. Also, now all the data frames will be skipped while termination. diffstat: src/http/v2/ngx_http_v2.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (22 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -3890,6 +3890,10 @@ ngx_http_v2_terminate_stream(ngx_http_v2 ngx_event_t *rev; ngx_connection_t *fc; + if (stream->rst_sent) { + return NGX_OK; + } + if (ngx_http_v2_send_rst_stream(h2c, stream->node->id, status) == NGX_ERROR) { @@ -3897,6 +3901,7 @@ ngx_http_v2_terminate_stream(ngx_http_v2 } stream->rst_sent = 1; + stream->skip_data = 1; fc = stream->request->connection; fc->error = 1; From mdounin at mdounin.ru Tue Oct 18 14:48:03 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:03 +0000 Subject: [nginx] HTTP/2: avoid adding Content-Length for requests without body. Message-ID: details: http://hg.nginx.org/nginx/rev/12b1df4c9944 branches: stable-1.10 changeset: 6754:12b1df4c9944 user: Valentin Bartenev date: Thu Jun 16 20:55:11 2016 +0300 description: HTTP/2: avoid adding Content-Length for requests without body. There is no reason to add the "Content-Length: 0" header to a proxied request without body if the header isn't presented in the original request. Thanks to Amazon. diffstat: src/http/v2/ngx_http_v2.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (23 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -3424,7 +3424,9 @@ ngx_http_v2_run_request(ngx_http_request return; } - r->headers_in.chunked = (r->headers_in.content_length_n == -1); + if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) { + r->headers_in.chunked = 1; + } ngx_http_process_request(r); } @@ -3638,7 +3640,7 @@ ngx_http_v2_process_request_body(ngx_htt rb->buf = NULL; } - if (r->headers_in.content_length_n == -1) { + if (r->headers_in.chunked) { r->headers_in.content_length_n = rb->received; } From mdounin at mdounin.ru Tue Oct 18 14:48:06 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:06 +0000 Subject: [nginx] HTTP/2: fixed the "http request count is zero" alert. Message-ID: details: http://hg.nginx.org/nginx/rev/e2f13011343e branches: stable-1.10 changeset: 6755:e2f13011343e user: Valentin Bartenev date: Thu Jun 16 20:55:11 2016 +0300 description: HTTP/2: fixed the "http request count is zero" alert. When the stream is terminated the HEADERS frame can still wait in the output queue. This frame can't be removed and must be sent to the client anyway, since HTTP/2 uses stateful compression for headers. So in order to postpone closing and freeing memory of such stream the special close stream handler is set to the write event. After the HEADERS frame is sent the write event is called and the stream will be finally closed. Some events like receiving a RST_STREAM can trigger the read handler of such stream in closing state and cause unexpected processing that can result in another attempt to finalize the request. To prevent it the read handler is now set to ngx_http_empty_handler. Thanks to Amazon. diffstat: src/http/v2/ngx_http_v2.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -3935,6 +3935,7 @@ ngx_http_v2_close_stream(ngx_http_v2_str if (stream->queued) { fc->write->handler = ngx_http_v2_close_stream_handler; + fc->read->handler = ngx_http_empty_handler; return; } From mdounin at mdounin.ru Tue Oct 18 14:48:08 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:08 +0000 Subject: [nginx] Sub filter: introduced the ngx_http_sub_match() function. Message-ID: details: http://hg.nginx.org/nginx/rev/521f5aa6e8fb branches: stable-1.10 changeset: 6756:521f5aa6e8fb user: Roman Arutyunyan date: Sat Jul 02 15:59:52 2016 +0300 description: Sub filter: introduced the ngx_http_sub_match() function. No functional changes. diffstat: src/http/modules/ngx_http_sub_filter_module.c | 83 ++++++++++++++++---------- 1 files changed, 52 insertions(+), 31 deletions(-) diffs (119 lines): diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c --- a/src/http/modules/ngx_http_sub_filter_module.c +++ b/src/http/modules/ngx_http_sub_filter_module.c @@ -84,6 +84,8 @@ static ngx_int_t ngx_http_sub_output(ngx ngx_http_sub_ctx_t *ctx); static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx); +static ngx_int_t ngx_http_sub_match(ngx_http_sub_ctx_t *ctx, ngx_int_t start, + ngx_str_t *m); static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -592,7 +594,7 @@ ngx_http_sub_output(ngx_http_request_t * static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx) { - u_char *p, *last, *pat, *pat_end, c; + u_char *p, c; ngx_str_t *m; ngx_int_t offset, start, next, end, len, rc; ngx_uint_t shift, i, j; @@ -641,41 +643,15 @@ ngx_http_sub_parse(ngx_http_request_t *r m = &match[i].match; - pat = m->data; - pat_end = m->data + m->len; - - if (start >= 0) { - p = ctx->pos + start; - - } else { - last = ctx->looked.data + ctx->looked.len; - p = last + start; + rc = ngx_http_sub_match(ctx, start, m); - while (p < last && pat < pat_end) { - if (ngx_tolower(*p) != *pat) { - goto next; - } - - p++; - pat++; - } - - p = ctx->pos; - } - - while (p < ctx->buf->last && pat < pat_end) { - if (ngx_tolower(*p) != *pat) { - goto next; - } - - p++; - pat++; + if (rc == NGX_DECLINED) { + goto next; } ctx->index = i; - if (pat != pat_end) { - /* partial match */ + if (rc == NGX_AGAIN) { goto again; } @@ -731,6 +707,51 @@ done: } +static ngx_int_t +ngx_http_sub_match(ngx_http_sub_ctx_t *ctx, ngx_int_t start, ngx_str_t *m) +{ + u_char *p, *last, *pat, *pat_end; + + pat = m->data; + pat_end = m->data + m->len; + + if (start >= 0) { + p = ctx->pos + start; + + } else { + last = ctx->looked.data + ctx->looked.len; + p = last + start; + + while (p < last && pat < pat_end) { + if (ngx_tolower(*p) != *pat) { + return NGX_DECLINED; + } + + p++; + pat++; + } + + p = ctx->pos; + } + + while (p < ctx->buf->last && pat < pat_end) { + if (ngx_tolower(*p) != *pat) { + return NGX_DECLINED; + } + + p++; + pat++; + } + + if (pat != pat_end) { + /* partial match */ + return NGX_AGAIN; + } + + return NGX_OK; +} + + static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { From mdounin at mdounin.ru Tue Oct 18 14:48:10 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:10 +0000 Subject: [nginx] Sub filter: eliminate unnecessary buffering. Message-ID: details: http://hg.nginx.org/nginx/rev/cc327c3caf4a branches: stable-1.10 changeset: 6757:cc327c3caf4a user: Roman Arutyunyan date: Sat Jul 02 15:59:53 2016 +0300 description: Sub filter: eliminate unnecessary buffering. Previously, when a buffer was processed by the sub filter, its final bytes could be buffered by the filter even if they don't match any pattern. This happened because the Boyer-Moore algorithm, employed by the sub filter since b9447fc457b4 (1.9.4), matches the last characters of patterns prior to checking other characters. If the last character is out of scope, initial bytes of a potential match are buffered until the last character is available. Now, after receiving a flush or recycled buffer, the filter performs additional checks to reduce the number of buffered bytes. The potential match is checked against the initial parts of all patterns. Non-matching bytes are not buffered. This improves processing of a chunked response from upstream by sending the entire chunks without buffering unless a partial match is found at the end of a chunk. diffstat: src/http/modules/ngx_http_sub_filter_module.c | 41 ++++++++++++++++++++++++-- 1 files changed, 37 insertions(+), 4 deletions(-) diffs (104 lines): diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c --- a/src/http/modules/ngx_http_sub_filter_module.c +++ b/src/http/modules/ngx_http_sub_filter_module.c @@ -83,7 +83,7 @@ static ngx_uint_t ngx_http_sub_cmp_index static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx); static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, - ngx_http_sub_ctx_t *ctx); + ngx_http_sub_ctx_t *ctx, ngx_uint_t flush); static ngx_int_t ngx_http_sub_match(ngx_http_sub_ctx_t *ctx, ngx_int_t start, ngx_str_t *m); @@ -287,6 +287,7 @@ ngx_http_sub_body_filter(ngx_http_reques ngx_int_t rc; ngx_buf_t *b; ngx_str_t *sub; + ngx_uint_t flush, last; ngx_chain_t *cl; ngx_http_sub_ctx_t *ctx; ngx_http_sub_match_t *match; @@ -328,6 +329,9 @@ ngx_http_sub_body_filter(ngx_http_reques ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http sub filter \"%V\"", &r->uri); + flush = 0; + last = 0; + while (ctx->in || ctx->buf) { if (ctx->buf == NULL) { @@ -336,11 +340,19 @@ ngx_http_sub_body_filter(ngx_http_reques ctx->pos = ctx->buf->pos; } + if (ctx->buf->flush || ctx->buf->recycled) { + flush = 1; + } + + if (ctx->in == NULL) { + last = flush; + } + b = NULL; while (ctx->pos < ctx->buf->last) { - rc = ngx_http_sub_parse(r, ctx); + rc = ngx_http_sub_parse(r, ctx, last); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "parse: %i, looked: \"%V\" %p-%p", @@ -592,7 +604,8 @@ ngx_http_sub_output(ngx_http_request_t * static ngx_int_t -ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx) +ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx, + ngx_uint_t flush) { u_char *p, c; ngx_str_t *m; @@ -604,6 +617,7 @@ ngx_http_sub_parse(ngx_http_request_t *r slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); tables = ctx->tables; + match = ctx->matches->elts; offset = ctx->offset; end = ctx->buf->last - ctx->pos; @@ -630,7 +644,6 @@ ngx_http_sub_parse(ngx_http_request_t *r /* a potential match */ start = offset - (ngx_int_t) tables->min_match_len + 1; - match = ctx->matches->elts; i = ngx_max(tables->index[c], ctx->index); j = tables->index[c + 1]; @@ -671,6 +684,26 @@ ngx_http_sub_parse(ngx_http_request_t *r ctx->index = 0; } + if (flush) { + for ( ;; ) { + start = offset - (ngx_int_t) tables->min_match_len + 1; + + if (start >= end) { + break; + } + + for (i = 0; i < ctx->matches->nelts; i++) { + m = &match[i].match; + + if (ngx_http_sub_match(ctx, start, m) == NGX_AGAIN) { + goto again; + } + } + + offset++; + } + } + again: ctx->offset = offset; From mdounin at mdounin.ru Tue Oct 18 14:48:13 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:13 +0000 Subject: [nginx] Updated PCRE used for win32 builds. Message-ID: details: http://hg.nginx.org/nginx/rev/de636b710cb1 branches: stable-1.10 changeset: 6758:de636b710cb1 user: Maxim Dounin date: Tue Jul 05 18:30:56 2016 +0300 description: Updated PCRE used for win32 builds. diffstat: misc/GNUmakefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -7,7 +7,7 @@ TEMP = tmp OBJS = objs.msvc8 OPENSSL = openssl-1.0.2h ZLIB = zlib-1.2.8 -PCRE = pcre-8.38 +PCRE = pcre-8.39 release: export From mdounin at mdounin.ru Tue Oct 18 14:48:15 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:15 +0000 Subject: [nginx] HTTP/2: always send GOAWAY while worker is shutting down. Message-ID: details: http://hg.nginx.org/nginx/rev/ee43fa9aff66 branches: stable-1.10 changeset: 6759:ee43fa9aff66 user: Valentin Bartenev date: Tue Jul 19 20:22:44 2016 +0300 description: HTTP/2: always send GOAWAY while worker is shutting down. Previously, if the worker process exited, GOAWAY was sent to connections in idle state, but connections with active streams were closed without GOAWAY. diffstat: src/http/v2/ngx_http_v2.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -615,7 +615,7 @@ ngx_http_v2_handle_connection(ngx_http_v } if (ngx_terminate || ngx_exiting) { - ngx_http_close_connection(c); + ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR); return; } From mdounin at mdounin.ru Tue Oct 18 14:48:18 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:18 +0000 Subject: [nginx] HTTP/2: prevented output of the HEADERS frame for canceled streams. Message-ID: details: http://hg.nginx.org/nginx/rev/9d61ecbe979e branches: stable-1.10 changeset: 6760:9d61ecbe979e user: Valentin Bartenev date: Tue Jul 19 20:22:44 2016 +0300 description: HTTP/2: prevented output of the HEADERS frame for canceled streams. It's useless to generate HEADERS if the stream has been canceled already. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (25 lines): diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -169,6 +169,12 @@ ngx_http_v2_header_filter(ngx_http_reque return NGX_OK; } + fc = r->connection; + + if (fc->error) { + return NGX_ERROR; + } + if (r->method == NGX_HTTP_HEAD) { r->header_only = 1; } @@ -259,8 +265,6 @@ ngx_http_v2_header_filter(ngx_http_reque len += 1 + ngx_http_v2_literal_size("Wed, 31 Dec 1986 18:00:00 GMT"); } - fc = r->connection; - if (r->headers_out.location && r->headers_out.location->value.len) { if (r->headers_out.location->value.data[0] == '/') { From mdounin at mdounin.ru Tue Oct 18 14:48:20 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:20 +0000 Subject: [nginx] HTTP/2: always handle streams in error state. Message-ID: details: http://hg.nginx.org/nginx/rev/73e62bd2ce69 branches: stable-1.10 changeset: 6761:73e62bd2ce69 user: Valentin Bartenev date: Tue Jul 19 20:22:44 2016 +0300 description: HTTP/2: always handle streams in error state. Previously, a stream could be closed by timeout if it was canceled while its send window was exhausted. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diffs (30 lines): diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -1317,18 +1317,20 @@ static ngx_inline void ngx_http_v2_handle_stream(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream) { - ngx_event_t *wev; + ngx_connection_t *fc; - if (stream->handled || stream->blocked || stream->exhausted) { + if (stream->handled || stream->blocked) { return; } - wev = stream->request->connection->write; + fc = stream->request->connection; - if (!wev->delayed) { - stream->handled = 1; - ngx_queue_insert_tail(&h2c->posted, &stream->queue); + if (!fc->error && (stream->exhausted || fc->write->delayed)) { + return; } + + stream->handled = 1; + ngx_queue_insert_tail(&h2c->posted, &stream->queue); } From mdounin at mdounin.ru Tue Oct 18 14:48:23 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:23 +0000 Subject: [nginx] HTTP/2: avoid sending output queue if there's nothing to send. Message-ID: details: http://hg.nginx.org/nginx/rev/078f17b2535b branches: stable-1.10 changeset: 6762:078f17b2535b user: Valentin Bartenev date: Tue Jul 19 20:30:21 2016 +0300 description: HTTP/2: avoid sending output queue if there's nothing to send. Particularly this fixes alerts on OS X and NetBSD systems when HTTP/2 is configured over plain TCP sockets. On these systems calling writev() with no data leads to EINVAL errors being logged as "writev() failed (22: Invalid argument) while processing HTTP/2 connection". diffstat: src/http/v2/ngx_http_v2.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diffs (20 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -410,6 +410,16 @@ ngx_http_v2_write_handler(ngx_event_t *w ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 write handler"); + if (h2c->last_out == NULL && !c->buffered) { + + if (wev->timer_set) { + ngx_del_timer(wev); + } + + ngx_http_v2_handle_connection(h2c); + return; + } + h2c->blocked = 1; rc = ngx_http_v2_send_output_queue(h2c); From mdounin at mdounin.ru Tue Oct 18 14:48:25 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:25 +0000 Subject: [nginx] HTTP/2: fixed send timer handling. Message-ID: details: http://hg.nginx.org/nginx/rev/4f8ad0faab3c branches: stable-1.10 changeset: 6763:4f8ad0faab3c user: Valentin Bartenev date: Tue Jul 19 20:31:09 2016 +0300 description: HTTP/2: fixed send timer handling. Checking for return value of c->send_chain() isn't sufficient since there are data can be left in the SSL buffer. Now the wew->ready flag is used instead. In particular, this fixed a connection leak in cases when all streams were closed, but there's still some data to be sent in the SSL buffer and the client forgot about the connection. diffstat: src/http/v2/ngx_http_v2.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -549,7 +549,7 @@ ngx_http_v2_send_output_queue(ngx_http_v c->tcp_nodelay = NGX_TCP_NODELAY_SET; } - if (cl) { + if (!wev->ready) { ngx_add_timer(wev, clcf->send_timeout); } else { From mdounin at mdounin.ru Tue Oct 18 14:48:28 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:28 +0000 Subject: [nginx] HTTP/2: refactored ngx_http_v2_send_output_queue(). Message-ID: details: http://hg.nginx.org/nginx/rev/edffb7defebe branches: stable-1.10 changeset: 6764:edffb7defebe user: Valentin Bartenev date: Tue Jul 19 20:34:02 2016 +0300 description: HTTP/2: refactored ngx_http_v2_send_output_queue(). Now it returns NGX_AGAIN if there's still data to be sent. diffstat: src/http/v2/ngx_http_v2.c | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-) diffs (44 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -478,7 +478,7 @@ ngx_http_v2_send_output_queue(ngx_http_v wev = c->write; if (!wev->ready) { - return NGX_OK; + return NGX_AGAIN; } cl = NULL; @@ -549,15 +549,6 @@ ngx_http_v2_send_output_queue(ngx_http_v c->tcp_nodelay = NGX_TCP_NODELAY_SET; } - if (!wev->ready) { - ngx_add_timer(wev, clcf->send_timeout); - - } else { - if (wev->timer_set) { - ngx_del_timer(wev); - } - } - for ( /* void */ ; out; out = fn) { fn = out->next; @@ -582,6 +573,15 @@ ngx_http_v2_send_output_queue(ngx_http_v h2c->last_out = frame; + if (!wev->ready) { + ngx_add_timer(wev, clcf->send_timeout); + return NGX_AGAIN; + } + + if (wev->timer_set) { + ngx_del_timer(wev); + } + return NGX_OK; error: From mdounin at mdounin.ru Tue Oct 18 14:48:30 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:30 +0000 Subject: [nginx] HTTP/2: flushing of the SSL buffer in transition to the idle state. Message-ID: details: http://hg.nginx.org/nginx/rev/85c3740b6745 branches: stable-1.10 changeset: 6765:85c3740b6745 user: Valentin Bartenev date: Tue Jul 19 20:34:17 2016 +0300 description: HTTP/2: flushing of the SSL buffer in transition to the idle state. It fixes potential connection leak if some unsent data was left in the SSL buffer. Particularly, that could happen when a client canceled the stream after the HEADERS frame has already been created. In this case no other frames might be produced and the HEADERS frame alone didn't flush the buffer. diffstat: src/http/v2/ngx_http_v2.c | 20 ++++++++++++++++++-- 1 files changed, 18 insertions(+), 2 deletions(-) diffs (37 lines): diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -599,7 +599,8 @@ error: static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c) { - ngx_connection_t *c; + ngx_int_t rc; + ngx_connection_t *c; ngx_http_v2_srv_conf_t *h2scf; if (h2c->last_out || h2c->processing) { @@ -614,7 +615,22 @@ ngx_http_v2_handle_connection(ngx_http_v } if (c->buffered) { - return; + h2c->blocked = 1; + + rc = ngx_http_v2_send_output_queue(h2c); + + h2c->blocked = 0; + + if (rc == NGX_ERROR) { + ngx_http_close_connection(c); + return; + } + + if (rc == NGX_AGAIN) { + return; + } + + /* rc == NGX_OK */ } h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, From mdounin at mdounin.ru Tue Oct 18 14:48:33 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:33 +0000 Subject: [nginx] SSL: guarded SSL_R_NO_CIPHERS_PASSED not present in OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/12c65ff24fd3 branches: stable-1.10 changeset: 6766:12c65ff24fd3 user: Sergey Kandaurov date: Mon Aug 08 13:44:49 2016 +0300 description: SSL: guarded SSL_R_NO_CIPHERS_PASSED not present in OpenSSL 1.1.0. It was removed in OpenSSL 1.1.0 Beta 3 (pre-release 6). It was not used since OpenSSL 1.0.1n and 1.0.2b. diffstat: src/event/ngx_event_openssl.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (13 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -1938,7 +1938,9 @@ ngx_ssl_connection_error(ngx_connection_ || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */ || n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */ || n == SSL_R_LENGTH_MISMATCH /* 159 */ +#ifdef SSL_R_NO_CIPHERS_PASSED || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ +#endif || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */ || n == SSL_R_NO_SHARED_CIPHER /* 193 */ From mdounin at mdounin.ru Tue Oct 18 14:48:35 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:35 +0000 Subject: [nginx] SSL: adopted session ticket handling for OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/e0d1c1e05eef branches: stable-1.10 changeset: 6767:e0d1c1e05eef user: Sergey Kandaurov date: Mon Aug 22 18:53:21 2016 +0300 description: SSL: adopted session ticket handling for OpenSSL 1.1.0. Return 1 in the SSL_CTX_set_tlsext_ticket_key_cb() callback function to indicate that a new session ticket is created, as per documentation. Until 1.1.0, OpenSSL didn't make a distinction between non-negative return values. See https://git.openssl.org/?p=openssl.git;a=commitdiff;h=5c753de for details. diffstat: src/event/ngx_event_openssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2900,7 +2900,7 @@ ngx_ssl_session_ticket_key_callback(ngx_ ngx_ssl_session_ticket_md(), NULL); ngx_memcpy(name, key[0].name, 16); - return 0; + return 1; } else { /* decrypt session ticket */ From mdounin at mdounin.ru Tue Oct 18 14:48:38 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:38 +0000 Subject: [nginx] Event pipe: do not set file's thread_handler if not needed. Message-ID: details: http://hg.nginx.org/nginx/rev/d9c180fcbfa7 branches: stable-1.10 changeset: 6768:d9c180fcbfa7 user: Maxim Dounin date: Thu Sep 01 20:05:23 2016 +0300 description: Event pipe: do not set file's thread_handler if not needed. This fixes a problem with aio threads and sendfile with aio_write switched off, as observed with range requests after fc72784b1f52 (1.9.13). Potential problems with sendfile in threads were previously described in 9fd738b85fad, and this seems to be one of them. The problem occurred as file's thread_handler was set to NULL by event pipe code after a sendfile thread task was scheduled. As a result, no sendfile completion code was executed, and the same buffer was additionally sent using non-threaded sendfile. Fix is to avoid modifying file's thread_handler if aio_write is switched off. Note that with "aio_write on" it is still possible that sendfile will use thread_handler as set by event pipe. This is believed to be safe though, as handlers used are compatible. diffstat: src/event/ngx_event_pipe.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diffs (20 lines): diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -815,10 +815,12 @@ ngx_event_pipe_write_chain_to_temp_file( } #if (NGX_THREADS) - p->temp_file->thread_write = p->thread_handler ? 1 : 0; - p->temp_file->file.thread_task = p->thread_task; - p->temp_file->file.thread_handler = p->thread_handler; - p->temp_file->file.thread_ctx = p->thread_ctx; + if (p->thread_handler) { + p->temp_file->thread_write = 1; + p->temp_file->file.thread_task = p->thread_task; + p->temp_file->file.thread_handler = p->thread_handler; + p->temp_file->file.thread_ctx = p->thread_ctx; + } #endif n = ngx_write_chain_to_temp_file(p->temp_file, out); From mdounin at mdounin.ru Tue Oct 18 14:48:40 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:40 +0000 Subject: [nginx] Updated OpenSSL used for win32 builds. Message-ID: details: http://hg.nginx.org/nginx/rev/5ba99eff0f33 branches: stable-1.10 changeset: 6769:5ba99eff0f33 user: Maxim Dounin date: Tue Oct 11 16:52:48 2016 +0300 description: Updated OpenSSL used for win32 builds. diffstat: misc/GNUmakefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -5,7 +5,7 @@ NGINX = nginx-$(VER) TEMP = tmp OBJS = objs.msvc8 -OPENSSL = openssl-1.0.2h +OPENSSL = openssl-1.0.2j ZLIB = zlib-1.2.8 PCRE = pcre-8.39 From mdounin at mdounin.ru Tue Oct 18 14:48:43 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 14:48:43 +0000 Subject: [nginx] SSL: default DH parameters compatible with OpenSSL 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/131bc715ce87 branches: stable-1.10 changeset: 6770:131bc715ce87 user: Maxim Dounin date: Tue Oct 18 17:25:38 2016 +0300 description: SSL: default DH parameters compatible with OpenSSL 1.1.0. This is a direct commit to stable as there is no corresponding code in mainline, default DH parameters were removed in 1aa9650a8154. diffstat: src/event/ngx_event_openssl.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) diffs (36 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -951,6 +951,8 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_ return NGX_ERROR; } +#if OPENSSL_VERSION_NUMBER < 0x10100005L + dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); @@ -960,6 +962,23 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_ return NGX_ERROR; } +#else + { + BIGNUM *p, *g; + + p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); + g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); + + if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "BN_bin2bn() failed"); + DH_free(dh); + BN_free(p); + BN_free(g); + return NGX_ERROR; + } + } +#endif + SSL_CTX_set_tmp_dh(ssl->ctx, dh); DH_free(dh); From igor at sysoev.ru Tue Oct 18 15:05:32 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 18 Oct 2016 15:05:32 +0000 Subject: [njs] Array.indexOf() and Array.lastIndexOf() have been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/fa9ced8246e5 branches: changeset: 208:fa9ced8246e5 user: Igor Sysoev date: Tue Oct 18 17:44:01 2016 +0300 description: Array.indexOf() and Array.lastIndexOf() have been fixed. diffstat: njs/njs_array.c | 2 +- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletions(-) diffs (25 lines): diff -r 59b3b4a0b535 -r fa9ced8246e5 njs/njs_array.c --- a/njs/njs_array.c Tue Oct 18 15:48:22 2016 +0300 +++ b/njs/njs_array.c Tue Oct 18 17:44:01 2016 +0300 @@ -996,7 +996,7 @@ njs_array_index_of(njs_vm_t *vm, njs_val index = -1; - if (nargs > 1) { + if (nargs > 1 && njs_is_array(&args[0])) { i = 0; array = args[0].data.u.array; length = array->length; diff -r 59b3b4a0b535 -r fa9ced8246e5 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 18 15:48:22 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 18 17:44:01 2016 +0300 @@ -2359,6 +2359,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [1,2,3,4,3,4]; a.indexOf(3, -10)"), nxt_string("2") }, + { nxt_string("[].indexOf.bind(0)(0, 0)"), + nxt_string("-1") }, + { nxt_string("var a = [1,2,3,4]; a.lastIndexOf()"), nxt_string("-1") }, From mdounin at mdounin.ru Tue Oct 18 15:13:36 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 15:13:36 +0000 Subject: [nginx] nginx-1.10.2-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/b98f9fdee487 branches: stable-1.10 changeset: 6771:b98f9fdee487 user: Maxim Dounin date: Tue Oct 18 18:03:12 2016 +0300 description: nginx-1.10.2-RELEASE diffstat: docs/xml/nginx/changes.xml | 115 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 115 insertions(+), 0 deletions(-) diffs (125 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,121 @@ + + + + +??? ??????? ????????? ??????????? ??????, +???????????? ?? ?????????????? ? ???????? SSL handshake, +?????? ???????????? ????? "421 Misdirected Request"; +??? ???????? ????????????? ? ?????????? HTTP/2-????????? +? ?????? ????????????? ?????????? ????????????. + + +the "421 Misdirected Request" response now used +when rejecting requests to a virtual server +different from one negotiated during an SSL handshake; +this improves interoperability with some HTTP/2 clients +when using client certificates. + + + + + +HTTP/2-??????? ?????? ????? ????? ????????? ???? ???????; +????????? http2_body_preread_size ????????? ??????? ?????? ??????, ??????? +????? ?????????????? ?? ????, ??? nginx ?????? ?????? ????. + + +HTTP/2 clients can now start sending request body immediately; +the "http2_body_preread_size" directive controls size of the buffer used +before nginx will start reading client request body. + + + + + +??? ????????????? HTTP/2 ? ????????? proxy_request_buffering +? ??????? ???????? ??? ????????? segmentation fault. + + +a segmentation fault might occur in a worker process +when using HTTP/2 and the "proxy_request_buffering" directive. + + + + + +??? ????????????? HTTP/2 +? ????????, ???????????? ?? ??????, +?????? ??????????? ?????? ????????? "Content-Length", +???? ???? ? ??????? ?? ???? ????. + + +the "Content-Length" request header line +was always added to requests passed to backends, +including requests without body, +when using HTTP/2. + + + + + +??? ????????????? HTTP/2 +? ????? ????? ?????????? ????????? "http request count is zero". + + +"http request count is zero" alerts might appear in logs +when using HTTP/2. + + + + + +??? ????????????? ????????? sub_filter +????? ???????????????? ?????? ??????, ??? ??? ??????????; +???????? ????????? ? 1.9.4. + + +unnecessary buffering might occur +when using the "sub_filter" directive; +the issue had appeared in 1.9.4. + + + + + +?????? ??????? ??? ????????????? HTTP/2. + + +socket leak when using HTTP/2. + + + + + +??? ????????????? ???????? "aio threads" ? sendfile +??? ???????????? ???????????? ?????; ?????? ????????? ? 1.9.13. + + +an incorrect response might be returned +when using the "aio threads" and "sendfile" directives; +the bug had appeared in 1.9.13. + + + + + +????????????? ? OpenSSL 1.1.0. + + +OpenSSL 1.1.0 compatibility. + + + + + + From mdounin at mdounin.ru Tue Oct 18 15:13:38 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 15:13:38 +0000 Subject: [nginx] release-1.10.2 tag Message-ID: details: http://hg.nginx.org/nginx/rev/9f6b75651432 branches: stable-1.10 changeset: 6772:9f6b75651432 user: Maxim Dounin date: Tue Oct 18 18:03:13 2016 +0300 description: release-1.10.2 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -400,3 +400,4 @@ 4106db71cbcb9c8274700199ac17e520902c6c0f 13070ecfda67397985f0e986eb9c42ecb46d05b5 release-1.9.15 d4b7edd7fa81cbf554ee3dcfe9de53ad6d1dbc69 release-1.10.0 7fcde9122088094471a97030161e347aa940f8ed release-1.10.1 +b98f9fdee487b00556bea6a24f8f976d7fd60795 release-1.10.2 From mdounin at mdounin.ru Tue Oct 18 16:49:56 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 16:49:56 +0000 Subject: [nginx] Mail: extensible auth methods in pop3 module. Message-ID: details: http://hg.nginx.org/nginx/rev/73b451d304c0 branches: changeset: 6773:73b451d304c0 user: Maxim Dounin date: Tue Oct 18 19:38:46 2016 +0300 description: Mail: extensible auth methods in pop3 module. diffstat: src/mail/ngx_mail_pop3_module.c | 94 ++++++++++++++++++++++++++++------------ 1 files changed, 66 insertions(+), 28 deletions(-) diffs (145 lines): diff --git a/src/mail/ngx_mail_pop3_module.c b/src/mail/ngx_mail_pop3_module.c --- a/src/mail/ngx_mail_pop3_module.c +++ b/src/mail/ngx_mail_pop3_module.c @@ -33,19 +33,13 @@ static ngx_conf_bitmask_t ngx_mail_pop3 }; -static ngx_str_t ngx_mail_pop3_auth_plain_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "." CRLF); - - -static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "CRAM-MD5" CRLF - "." CRLF); +static ngx_str_t ngx_mail_pop3_auth_methods_names[] = { + ngx_string("PLAIN"), + ngx_string("LOGIN"), + ngx_null_string, /* APOP */ + ngx_string("CRAM-MD5"), + ngx_null_string /* NONE */ +}; static ngx_mail_protocol_t ngx_mail_pop3_protocol = { @@ -140,13 +134,17 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t u_char *p; size_t size, stls_only_size; ngx_str_t *c, *d; - ngx_uint_t i; + ngx_uint_t i, m; ngx_conf_merge_bitmask_value(conf->auth_methods, prev->auth_methods, (NGX_CONF_BITMASK_SET |NGX_MAIL_AUTH_PLAIN_ENABLED)); + if (conf->auth_methods & NGX_MAIL_AUTH_PLAIN_ENABLED) { + conf->auth_methods |= NGX_MAIL_AUTH_LOGIN_ENABLED; + } + if (conf->capabilities.nelts == 0) { conf->capabilities = prev->capabilities; } @@ -179,11 +177,15 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t stls_only_size += c[i].len + sizeof(CRLF) - 1; } - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; + size += sizeof("SASL") - 1 + sizeof(CRLF) - 1; - } else { - size += sizeof("SASL LOGIN PLAIN" CRLF) - 1; + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + size += 1 + ngx_mail_pop3_auth_methods_names[i].len; + } } p = ngx_pnalloc(cf->pool, size); @@ -202,15 +204,21 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *p++ = CR; *p++ = LF; } - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF, - sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1); + p = ngx_cpymem(p, "SASL", sizeof("SASL") - 1); - } else { - p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF, - sizeof("SASL LOGIN PLAIN" CRLF) - 1); + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + *p++ = ' '; + p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data, + ngx_mail_pop3_auth_methods_names[i].len); + } } + *p++ = CR; *p++ = LF; + *p++ = '.'; *p++ = CR; *p = LF; @@ -231,13 +239,43 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *p++ = '.'; *p++ = CR; *p = LF; - if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability; + size = sizeof("+OK methods supported:" CRLF) - 1 + + sizeof("." CRLF) - 1; - } else { - conf->auth_capability = ngx_mail_pop3_auth_plain_capability; + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + size += ngx_mail_pop3_auth_methods_names[i].len + + sizeof(CRLF) - 1; + } } + p = ngx_pnalloc(cf->pool, size); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + conf->auth_capability.data = p; + conf->auth_capability.len = size; + + p = ngx_cpymem(p, "+OK methods supported:" CRLF, + sizeof("+OK methods supported:" CRLF) - 1); + + for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; + m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <<= 1, i++) + { + if (m & conf->auth_methods) { + p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data, + ngx_mail_pop3_auth_methods_names[i].len); + *p++ = CR; *p++ = LF; + } + } + + *p++ = '.'; *p++ = CR; *p = LF; + p = ngx_pnalloc(cf->pool, stls_only_size); if (p == NULL) { From mdounin at mdounin.ru Tue Oct 18 16:49:59 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 16:49:59 +0000 Subject: [nginx] Mail: support SASL EXTERNAL (RFC 4422). Message-ID: details: http://hg.nginx.org/nginx/rev/bcb107bb89cd branches: changeset: 6774:bcb107bb89cd user: Rob N ? date: Sat Oct 08 18:05:00 2016 +1100 description: Mail: support SASL EXTERNAL (RFC 4422). This is needed to allow TLS client certificate auth to work. With ssl_verify_client configured, the auth daemon can choose to allow the connection to proceed based on the certificate data. This has been tested with Thunderbird for IMAP only. I've not yet found a client that will do client certificate auth for POP3 or SMTP, and the method is not really documented anywhere that I can find. That said, its simple enough that the way I've done is probably right. diffstat: src/mail/ngx_mail.h | 13 ++++++++++--- src/mail/ngx_mail_auth_http_module.c | 1 + src/mail/ngx_mail_handler.c | 34 ++++++++++++++++++++++++++++++++++ src/mail/ngx_mail_imap_handler.c | 11 +++++++++++ src/mail/ngx_mail_imap_module.c | 6 ++++-- src/mail/ngx_mail_parse.c | 22 ++++++++++++++++++---- src/mail/ngx_mail_pop3_handler.c | 11 +++++++++++ src/mail/ngx_mail_pop3_module.c | 10 ++++++---- src/mail/ngx_mail_smtp_handler.c | 11 +++++++++++ src/mail/ngx_mail_smtp_module.c | 6 ++++-- 10 files changed, 110 insertions(+), 15 deletions(-) diffs (360 lines): diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -132,7 +132,8 @@ typedef enum { ngx_pop3_auth_login_username, ngx_pop3_auth_login_password, ngx_pop3_auth_plain, - ngx_pop3_auth_cram_md5 + ngx_pop3_auth_cram_md5, + ngx_pop3_auth_external } ngx_pop3_state_e; @@ -142,6 +143,7 @@ typedef enum { ngx_imap_auth_login_password, ngx_imap_auth_plain, ngx_imap_auth_cram_md5, + ngx_imap_auth_external, ngx_imap_login, ngx_imap_user, ngx_imap_passwd @@ -154,6 +156,7 @@ typedef enum { ngx_smtp_auth_login_password, ngx_smtp_auth_plain, ngx_smtp_auth_cram_md5, + ngx_smtp_auth_external, ngx_smtp_helo, ngx_smtp_helo_xclient, ngx_smtp_helo_from, @@ -285,14 +288,16 @@ typedef struct { #define NGX_MAIL_AUTH_LOGIN_USERNAME 2 #define NGX_MAIL_AUTH_APOP 3 #define NGX_MAIL_AUTH_CRAM_MD5 4 -#define NGX_MAIL_AUTH_NONE 5 +#define NGX_MAIL_AUTH_EXTERNAL 5 +#define NGX_MAIL_AUTH_NONE 6 #define NGX_MAIL_AUTH_PLAIN_ENABLED 0x0002 #define NGX_MAIL_AUTH_LOGIN_ENABLED 0x0004 #define NGX_MAIL_AUTH_APOP_ENABLED 0x0008 #define NGX_MAIL_AUTH_CRAM_MD5_ENABLED 0x0010 -#define NGX_MAIL_AUTH_NONE_ENABLED 0x0020 +#define NGX_MAIL_AUTH_EXTERNAL_ENABLED 0x0020 +#define NGX_MAIL_AUTH_NONE_ENABLED 0x0040 #define NGX_MAIL_PARSE_INVALID_COMMAND 20 @@ -377,6 +382,8 @@ ngx_int_t ngx_mail_auth_login_password(n ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c, char *prefix, size_t len); ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c); +ngx_int_t ngx_mail_auth_external(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n); ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c); void ngx_mail_send(ngx_event_t *wev); diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c +++ b/src/mail/ngx_mail_auth_http_module.c @@ -151,6 +151,7 @@ static ngx_str_t ngx_mail_auth_http_me ngx_string("plain"), ngx_string("apop"), ngx_string("cram-md5"), + ngx_string("external"), ngx_string("none") }; diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -612,6 +612,40 @@ ngx_mail_auth_cram_md5(ngx_mail_session_ } +ngx_int_t +ngx_mail_auth_external(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n) +{ + ngx_str_t *arg, external; + + arg = s->args.elts; + + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, + "mail auth external: \"%V\"", &arg[n]); + + external.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len)); + if (external.data == NULL) { + return NGX_ERROR; + } + + if (ngx_decode_base64(&external, &arg[n]) != NGX_OK) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent invalid base64 encoding in AUTH EXTERNAL command"); + return NGX_MAIL_PARSE_INVALID_COMMAND; + } + + s->login.len = external.len; + s->login.data = external.data; + + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, + "mail auth external: \"%V\"", &s->login); + + s->auth_method = NGX_MAIL_AUTH_EXTERNAL; + + return NGX_DONE; +} + + void ngx_mail_send(ngx_event_t *wev) { diff --git a/src/mail/ngx_mail_imap_handler.c b/src/mail/ngx_mail_imap_handler.c --- a/src/mail/ngx_mail_imap_handler.c +++ b/src/mail/ngx_mail_imap_handler.c @@ -222,6 +222,10 @@ ngx_mail_imap_auth_state(ngx_event_t *re case ngx_imap_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_imap_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } else if (rc == NGX_IMAP_NEXT) { @@ -399,6 +403,13 @@ ngx_mail_imap_authenticate(ngx_mail_sess } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, imap_username); + s->mail_state = ngx_imap_auth_external; + + return NGX_OK; } return rc; diff --git a/src/mail/ngx_mail_imap_module.c b/src/mail/ngx_mail_imap_module.c --- a/src/mail/ngx_mail_imap_module.c +++ b/src/mail/ngx_mail_imap_module.c @@ -29,6 +29,7 @@ static ngx_conf_bitmask_t ngx_mail_imap { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_null_string, 0 } }; @@ -38,6 +39,7 @@ static ngx_str_t ngx_mail_imap_auth_met ngx_string("AUTH=LOGIN"), ngx_null_string, /* APOP */ ngx_string("AUTH=CRAM-MD5"), + ngx_string("AUTH=EXTERNAL"), ngx_null_string /* NONE */ }; @@ -179,7 +181,7 @@ ngx_mail_imap_merge_srv_conf(ngx_conf_t } for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -205,7 +207,7 @@ ngx_mail_imap_merge_srv_conf(ngx_conf_t auth = p; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c --- a/src/mail/ngx_mail_parse.c +++ b/src/mail/ngx_mail_parse.c @@ -905,13 +905,27 @@ ngx_mail_auth_parse(ngx_mail_session_t * if (arg[0].len == 8) { - if (s->args.nelts != 1) { - return NGX_MAIL_PARSE_INVALID_COMMAND; + if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) { + + if (s->args.nelts != 1) { + return NGX_MAIL_PARSE_INVALID_COMMAND; + } + + return NGX_MAIL_AUTH_CRAM_MD5; } - if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) { - return NGX_MAIL_AUTH_CRAM_MD5; + if (ngx_strncasecmp(arg[0].data, (u_char *) "EXTERNAL", 8) == 0) { + + if (s->args.nelts == 1) { + return NGX_MAIL_AUTH_EXTERNAL; + } + + if (s->args.nelts == 2) { + return ngx_mail_auth_external(s, c, 1); + } } + + return NGX_MAIL_PARSE_INVALID_COMMAND; } return NGX_MAIL_PARSE_INVALID_COMMAND; diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c +++ b/src/mail/ngx_mail_pop3_handler.c @@ -240,6 +240,10 @@ ngx_mail_pop3_auth_state(ngx_event_t *re case ngx_pop3_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_pop3_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } @@ -494,6 +498,13 @@ ngx_mail_pop3_auth(ngx_mail_session_t *s } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, pop3_username); + s->mail_state = ngx_pop3_auth_external; + + return NGX_OK; } return rc; diff --git a/src/mail/ngx_mail_pop3_module.c b/src/mail/ngx_mail_pop3_module.c --- a/src/mail/ngx_mail_pop3_module.c +++ b/src/mail/ngx_mail_pop3_module.c @@ -29,6 +29,7 @@ static ngx_conf_bitmask_t ngx_mail_pop3 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_null_string, 0 } }; @@ -38,6 +39,7 @@ static ngx_str_t ngx_mail_pop3_auth_met ngx_string("LOGIN"), ngx_null_string, /* APOP */ ngx_string("CRAM-MD5"), + ngx_string("EXTERNAL"), ngx_null_string /* NONE */ }; @@ -180,7 +182,7 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t size += sizeof("SASL") - 1 + sizeof(CRLF) - 1; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -207,7 +209,7 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t p = ngx_cpymem(p, "SASL", sizeof("SASL") - 1); for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -243,7 +245,7 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t + sizeof("." CRLF) - 1; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -264,7 +266,7 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t sizeof("+OK methods supported:" CRLF) - 1); for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c +++ b/src/mail/ngx_mail_smtp_handler.c @@ -485,6 +485,10 @@ ngx_mail_smtp_auth_state(ngx_event_t *re case ngx_smtp_auth_cram_md5: rc = ngx_mail_auth_cram_md5(s, c); break; + + case ngx_smtp_auth_external: + rc = ngx_mail_auth_external(s, c, 0); + break; } } @@ -652,6 +656,13 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s } return NGX_ERROR; + + case NGX_MAIL_AUTH_EXTERNAL: + + ngx_str_set(&s->out, smtp_username); + s->mail_state = ngx_smtp_auth_external; + + return NGX_OK; } return rc; diff --git a/src/mail/ngx_mail_smtp_module.c b/src/mail/ngx_mail_smtp_module.c --- a/src/mail/ngx_mail_smtp_module.c +++ b/src/mail/ngx_mail_smtp_module.c @@ -21,6 +21,7 @@ static ngx_conf_bitmask_t ngx_mail_smtp { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED }, { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED }, { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED }, + { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED }, { ngx_string("none"), NGX_MAIL_AUTH_NONE_ENABLED }, { ngx_null_string, 0 } }; @@ -31,6 +32,7 @@ static ngx_str_t ngx_mail_smtp_auth_met ngx_string("LOGIN"), ngx_null_string, /* APOP */ ngx_string("CRAM-MD5"), + ngx_string("EXTERNAL"), ngx_null_string /* NONE */ }; @@ -207,7 +209,7 @@ ngx_mail_smtp_merge_srv_conf(ngx_conf_t auth_enabled = 0; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { @@ -250,7 +252,7 @@ ngx_mail_smtp_merge_srv_conf(ngx_conf_t *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H'; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; + m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { if (m & conf->auth_methods) { From vbart at nginx.com Tue Oct 18 17:47:06 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 18 Oct 2016 17:47:06 +0000 Subject: [nginx] SSL: overcame possible buffer over-read in ngx_ssl_error(). Message-ID: details: http://hg.nginx.org/nginx/rev/8081e1f3ab8b branches: changeset: 6775:8081e1f3ab8b user: Valentin Bartenev date: Tue Oct 18 20:46:06 2016 +0300 description: SSL: overcame possible buffer over-read in ngx_ssl_error(). It appeared that ERR_error_string_n() cannot handle zero buffer size well enough and causes over-read. The problem has also been fixed in OpenSSL: https://git.openssl.org/?p=openssl.git;h=e5c1361580d8de79682958b04a5f0d262e680f8b diffstat: src/event/ngx_event_openssl.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r bcb107bb89cd -r 8081e1f3ab8b src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Sat Oct 08 18:05:00 2016 +1100 +++ b/src/event/ngx_event_openssl.c Tue Oct 18 20:46:06 2016 +0300 @@ -2137,7 +2137,9 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_ break; } - if (p >= last) { + /* ERR_error_string_n() requires at least one byte */ + + if (p >= last - 1) { goto next; } From mdounin at mdounin.ru Tue Oct 18 18:25:52 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 18 Oct 2016 21:25:52 +0300 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. In-Reply-To: References: Message-ID: <20161018182551.GR73038@mdounin.ru> Hello! On Thu, Oct 13, 2016 at 04:45:23PM +0800, ?? wrote: > # HG changeset patch > # User hucongcong > # Date 1476342771 -28800 > # Thu Oct 13 15:12:51 2016 +0800 > # Node ID 93bad8b82169245db6d4fe4e6b6c823221ee6a38 > # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 > Http mp4: replace strtod() with improved ngx_atofp() because precision problem. > > function prototype is ngx_atofp(u_char *line, size_t n, size_t point). > use case based on the old version: > ngx_atofp("12.2193", 7, 0) returns NGX_ERROR, > ngx_atofp("12.2193", 7, 2) returns NGX_ERROR. > now, allow point = 0 or point less than the number of fractional digits. > ngx_atofp("12.2193", 7, 0) returns 12, > ngx_atofp("12.2193", 7, 2) returns 1221. > retained all the required or right feature at the same time, e.g., > ngx_atofp("10.5", 4, 2) returns 1050. > > deprecated strtod() in ngx_http_mp4_module, since the precision problem, > which was metioned in http://stackoverflow.com/questions/18361261, e.g., > (int) (strtod((char *) "32.480", NULL) * 1000) returns 32479. > another way to solve this problem is like this round(strtod()), e.g., > (int) round((strtod((char *) "32.480", NULL) * 1000)) returns 32480, > but its not necessary, since we have a better ngx_atofp(). > > diff -r 7cdf69d012f0 -r 93bad8b82169 src/core/ngx_string.c > --- a/src/core/ngx_string.c Tue Oct 11 18:03:01 2016 +0300 > +++ b/src/core/ngx_string.c Thu Oct 13 15:12:51 2016 +0800 > @@ -945,8 +945,8 @@ > > for (value = 0; n--; line++) { > > - if (point == 0) { > - return NGX_ERROR; > + if (dot && point == 0) { > + break; > } > > if (*line == '.') { With such a change it won't be possible to detect errors in other places where ngx_atofp() is used. In particular, something like split_clients $remote_addr $foo { 0.015% 1; * 2; } will silently discard trailing 5. Moreover, even something like split_clients $remote_addr $foo { 0.01foobar% 1; * 2; } will be silently accepted. [...] -- Maxim Dounin http://nginx.org/ From piotrsikora at google.com Tue Oct 18 20:58:01 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 18 Oct 2016 13:58:01 -0700 Subject: [PATCH 1 of 6] SSL: define NGX_SSL_VERIFY constants In-Reply-To: <653b04653271346c63ab.1471480162@piotrsikora.sfo.corp.google.com> References: <653b04653271346c63ab.1471480162@piotrsikora.sfo.corp.google.com> Message-ID: Hey, > # HG changeset patch > # User Piotr Sikora > # Date 1471428975 25200 > # Wed Aug 17 03:16:15 2016 -0700 > # Node ID 653b04653271346c63ab5f3daced807228eed5ac > # Parent c131f20c9562387f94a268440594c288725d3ba8 > SSL: define NGX_SSL_VERIFY constants. > > No binary changes. > > Signed-off-by: Piotr Sikora Ping. Best regards, Piotr Sikora From piotrsikora at google.com Tue Oct 18 20:58:26 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 18 Oct 2016 13:58:26 -0700 Subject: [PATCH 2 of 6] SSL: pull common SSL defines into OpenSSL module In-Reply-To: <788c6187bdbd72787ba2.1471480163@piotrsikora.sfo.corp.google.com> References: <653b04653271346c63ab.1471480162@piotrsikora.sfo.corp.google.com> <788c6187bdbd72787ba2.1471480163@piotrsikora.sfo.corp.google.com> Message-ID: Hey, > # HG changeset patch > # User Piotr Sikora > # Date 1471428980 25200 > # Wed Aug 17 03:16:20 2016 -0700 > # Node ID 788c6187bdbd72787ba24505731e42b6a2307be3 > # Parent 653b04653271346c63ab5f3daced807228eed5ac > SSL: pull common SSL defines into OpenSSL module. > > Those values are OpenSSL-specific anyway. > > No binary changes (without reorder in ngx_mail_ssl_module). > > Signed-off-by: Piotr Sikora Ping. Best regards, Piotr Sikora From piotrsikora at google.com Tue Oct 18 20:58:50 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 18 Oct 2016 13:58:50 -0700 Subject: [PATCH 3 of 6] SSL: pull common SSL options into OpenSSL module In-Reply-To: <99c2f52beae28567bf2f.1471480164@piotrsikora.sfo.corp.google.com> References: <653b04653271346c63ab.1471480162@piotrsikora.sfo.corp.google.com> <99c2f52beae28567bf2f.1471480164@piotrsikora.sfo.corp.google.com> Message-ID: Hey, > # HG changeset patch > # User Piotr Sikora > # Date 1471428985 25200 > # Wed Aug 17 03:16:25 2016 -0700 > # Node ID 99c2f52beae28567bf2f8501d1a182cd20004c71 > # Parent 788c6187bdbd72787ba24505731e42b6a2307be3 > SSL: pull common SSL options into OpenSSL module. > > No functional changes. > > Signed-off-by: Piotr Sikora Ping. Best regards, Piotr Sikora From mdounin at mdounin.ru Tue Oct 18 23:18:00 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 19 Oct 2016 02:18:00 +0300 Subject: [PATCH 1 of 6] SSL: define NGX_SSL_VERIFY constants In-Reply-To: References: <653b04653271346c63ab.1471480162@piotrsikora.sfo.corp.google.com> Message-ID: <20161018231800.GT73038@mdounin.ru> Hello! On Tue, Oct 18, 2016 at 01:58:01PM -0700, Piotr Sikora wrote: > Hey, > > > # HG changeset patch > > # User Piotr Sikora > > # Date 1471428975 25200 > > # Wed Aug 17 03:16:15 2016 -0700 > > # Node ID 653b04653271346c63ab5f3daced807228eed5ac > > # Parent c131f20c9562387f94a268440594c288725d3ba8 > > SSL: define NGX_SSL_VERIFY constants. > > > > No binary changes. > > > > Signed-off-by: Piotr Sikora > > Ping. You may want to take a look at this message: http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008757.html -- Maxim Dounin http://nginx.org/ From piotrsikora at google.com Tue Oct 18 23:35:54 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 18 Oct 2016 16:35:54 -0700 Subject: [PATCH 1 of 6] SSL: define NGX_SSL_VERIFY constants In-Reply-To: <20161018231800.GT73038@mdounin.ru> References: <653b04653271346c63ab.1471480162@piotrsikora.sfo.corp.google.com> <20161018231800.GT73038@mdounin.ru> Message-ID: Hey Maxim, > You may want to take a look at this message: > > http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008757.html 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. Best regards, Piotr Sikora From hucong.c at foxmail.com Wed Oct 19 06:43:24 2016 From: hucong.c at foxmail.com (=?gb18030?B?uvq0zyAoaHVjYyk=?=) Date: Wed, 19 Oct 2016 14:43:24 +0800 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. Message-ID: Hello! Thanks for reminding me! Illegal character should be checked also error detection in configration parser is needed. Considering that ngx_atofp() was used in some 3rd party modules, Would nginx-devel accept a new function like ngx_ato??() or lround(strtod()), or just let strtod() alone? #lround(strtod()) --- a/src/http/modules/ngx_http_mp4_module.c +++ b/src/http/modules/ngx_http_mp4_module.c @@ -542,7 +542,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r) */ ngx_set_errno(0); - start = (int) (strtod((char *) value.data, NULL) * 1000); + start = (int) (lround(strtod((char *) value.data, NULL) * 1000)); if (ngx_errno != 0) { start = -1; @@ -552,7 +552,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r) if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) { ngx_set_errno(0); - end = (int) (strtod((char *) value.data, NULL) * 1000); + end = (int) (lround(strtod((char *) value.data, NULL) * 1000)); #new function +ngx_int_t +ngx_atopi(u_char *line, size_t n, size_t point) +{ + ngx_int_t value, cutoff, cutlim; + ngx_uint_t dot; + + if (n == 0) { + return NGX_ERROR; + } + + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; + + dot = 0; + + for (value = 0; n--; line++) { + + if (*line == '.') { + if (dot) { + return NGX_ERROR; + } + + dot = 1; + continue; + } + + if (*line < '0' || *line > '9') { + return NGX_ERROR; + } + + if (dot && point == 0) { + continue; + } + + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + + value = value * 10 + (*line - '0'); + point -= dot; + } + + while (point--) { + if (value > cutoff) { + return NGX_ERROR; + } + + value = value * 10; + } + + return value; +} ------------------ Original ------------------ From: "Maxim Dounin";; Send time: Wednesday, Oct 19, 2016 2:25 AM To: "nginx-devel"; Subject: Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. Hello! On Thu, Oct 13, 2016 at 04:45:23PM +0800, ?? wrote: > # HG changeset patch > # User hucongcong > # Date 1476342771 -28800 > # Thu Oct 13 15:12:51 2016 +0800 > # Node ID 93bad8b82169245db6d4fe4e6b6c823221ee6a38 > # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 > Http mp4: replace strtod() with improved ngx_atofp() because precision problem. > > function prototype is ngx_atofp(u_char *line, size_t n, size_t point). > use case based on the old version: > ngx_atofp("12.2193", 7, 0) returns NGX_ERROR, > ngx_atofp("12.2193", 7, 2) returns NGX_ERROR. > now, allow point = 0 or point less than the number of fractional digits. > ngx_atofp("12.2193", 7, 0) returns 12, > ngx_atofp("12.2193", 7, 2) returns 1221. > retained all the required or right feature at the same time, e.g., > ngx_atofp("10.5", 4, 2) returns 1050. > > deprecated strtod() in ngx_http_mp4_module, since the precision problem, > which was metioned in http://stackoverflow.com/questions/18361261, e.g., > (int) (strtod((char *) "32.480", NULL) * 1000) returns 32479. > another way to solve this problem is like this round(strtod()), e.g., > (int) round((strtod((char *) "32.480", NULL) * 1000)) returns 32480, > but its not necessary, since we have a better ngx_atofp(). > > diff -r 7cdf69d012f0 -r 93bad8b82169 src/core/ngx_string.c > --- a/src/core/ngx_string.c Tue Oct 11 18:03:01 2016 +0300 > +++ b/src/core/ngx_string.c Thu Oct 13 15:12:51 2016 +0800 > @@ -945,8 +945,8 @@ > > for (value = 0; n--; line++) { > > - if (point == 0) { > - return NGX_ERROR; > + if (dot && point == 0) { > + break; > } > > if (*line == '.') { With such a change it won't be possible to detect errors in other places where ngx_atofp() is used. In particular, something like split_clients $remote_addr $foo { 0.015% 1; * 2; } will silently discard trailing 5. Moreover, even something like split_clients $remote_addr $foo { 0.01foobar% 1; * 2; } will be silently accepted. [...] -- 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 piotrsikora at google.com Wed Oct 19 07:51:30 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 19 Oct 2016 00:51:30 -0700 Subject: [PATCH] Upstream: fix warning when building with BoringSSL In-Reply-To: <20161003173822.GF73038@mdounin.ru> References: <8c3706ffdc9bde38ef50.1475071847@mandy.local> <20161003173822.GF73038@mdounin.ru> Message-ID: Hey Maxim, > I have no strong objections, but the patch as you've submitted > casts to "const char *", while just "char *" should be enough. While cast to "char *" also works, I must admit that I'm confused as to why do you prefer to cast to a type that "should be enough" instead of a type that's expected by the function. Anyway, either one is an improvement over current situation, so please commit. Best regards, Piotr Sikora From piotrsikora at google.com Wed Oct 19 07:51:36 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 19 Oct 2016 00:51:36 -0700 Subject: [PATCH] SSL: decrease log level of SSL_R_NO_RENEGOTIATION to "info" Message-ID: # HG changeset patch # User Piotr Sikora # Date 1476859304 25200 # Tue Oct 18 23:41:44 2016 -0700 # Node ID ae85978091f832d27d862e468ee5e4cbfb18da11 # Parent 8081e1f3ab8b9ccb4e2d7f9240cbfb8e404a3c95 SSL: decrease log level of SSL_R_NO_RENEGOTIATION to "info". Previously, "no renegotiation" error was logged at the "critical" level when using BoringSSL, which rejects renegotiation at the protocol level. Signed-off-by: Piotr Sikora diff -r 8081e1f3ab8b -r ae85978091f8 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2045,6 +2045,9 @@ ngx_ssl_connection_error(ngx_connection_ #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED /* 338 */ #endif +#ifdef SSL_R_NO_RENEGOTIATION + || n == SSL_R_NO_RENEGOTIATION /* 339 */ +#endif #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING /* 345 */ #endif From piotrsikora at google.com Wed Oct 19 07:51:43 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 19 Oct 2016 00:51:43 -0700 Subject: [PATCH 1 of 2] HTTP: add support for "429 Too Many Requests" response (RFC6585) Message-ID: <1eec5355ef1e4a8b0aec.1476863503@piotrsikora.sfo.corp.google.com> # 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. Signed-off-by: Piotr Sikora diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -211,6 +211,7 @@ static ngx_conf_bitmask_t ngx_http_fast { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -220,6 +220,7 @@ static ngx_conf_bitmask_t ngx_http_prox { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -82,6 +82,7 @@ static ngx_conf_bitmask_t ngx_http_scgi_ { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -114,6 +114,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -100,12 +100,16 @@ static ngx_str_t ngx_http_status_lines[] ngx_null_string, /* "419 unused" */ ngx_null_string, /* "420 unused" */ ngx_string("421 Misdirected Request"), + ngx_null_string, /* "422 Unprocessable Entity" */ + ngx_null_string, /* "423 Locked" */ + ngx_null_string, /* "424 Failed Dependency" */ + ngx_null_string, /* "425 unused" */ + ngx_null_string, /* "426 Upgrade Required" */ + ngx_null_string, /* "427 unused" */ + ngx_null_string, /* "428 Precondition Required" */ + ngx_string("429 Too Many Requests"), - /* ngx_null_string, */ /* "422 Unprocessable Entity" */ - /* ngx_null_string, */ /* "423 Locked" */ - /* ngx_null_string, */ /* "424 Failed Dependency" */ - -#define NGX_HTTP_LAST_4XX 422 +#define NGX_HTTP_LAST_4XX 430 #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string("500 Internal Server Error"), diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -96,6 +96,7 @@ #define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE 415 #define NGX_HTTP_RANGE_NOT_SATISFIABLE 416 #define NGX_HTTP_MISDIRECTED_REQUEST 421 +#define NGX_HTTP_TOO_MANY_REQUESTS 429 /* Our own HTTP codes */ diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -218,6 +218,14 @@ static char ngx_http_error_421_page[] = ; +static char ngx_http_error_429_page[] = +"" CRLF +"429 Too Many Requests" CRLF +"" CRLF +"

429 Too Many Requests

" CRLF +; + + static char ngx_http_error_494_page[] = "" CRLF "400 Request Header Or Cookie Too Large" @@ -347,8 +355,16 @@ static ngx_str_t ngx_http_error_pages[] ngx_null_string, /* 419 */ ngx_null_string, /* 420 */ ngx_string(ngx_http_error_421_page), + ngx_null_string, /* 422 */ + ngx_null_string, /* 423 */ + ngx_null_string, /* 424 */ + ngx_null_string, /* 425 */ + ngx_null_string, /* 426 */ + ngx_null_string, /* 427 */ + ngx_null_string, /* 428 */ + ngx_string(ngx_http_error_429_page), -#define NGX_HTTP_LAST_4XX 422 +#define NGX_HTTP_LAST_4XX 430 #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string(ngx_http_error_494_page), /* 494, request header too large */ diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -422,6 +422,7 @@ static ngx_http_upstream_next_t ngx_htt { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 }, { 403, NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { 429, NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { 0, 0 } }; @@ -3951,7 +3952,8 @@ ngx_http_upstream_next(ngx_http_request_ if (u->peer.sockaddr) { if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_403 - || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) + || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404 + || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_429) { state = NGX_PEER_NEXT; @@ -3991,6 +3993,10 @@ ngx_http_upstream_next(ngx_http_request_ status = NGX_HTTP_NOT_FOUND; break; + case NGX_HTTP_UPSTREAM_FT_HTTP_429: + status = NGX_HTTP_TOO_MANY_REQUESTS; + break; + /* * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING * never reach here diff -r 8081e1f3ab8b -r 1eec5355ef1e src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -26,10 +26,11 @@ #define NGX_HTTP_UPSTREAM_FT_HTTP_504 0x00000080 #define NGX_HTTP_UPSTREAM_FT_HTTP_403 0x00000100 #define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000200 -#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000400 -#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000800 -#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00001000 -#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00002000 +#define NGX_HTTP_UPSTREAM_FT_HTTP_429 0x00000400 +#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000800 +#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00001000 +#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00002000 +#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00004000 #define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000 #define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000 @@ -38,7 +39,8 @@ |NGX_HTTP_UPSTREAM_FT_HTTP_503 \ |NGX_HTTP_UPSTREAM_FT_HTTP_504 \ |NGX_HTTP_UPSTREAM_FT_HTTP_403 \ - |NGX_HTTP_UPSTREAM_FT_HTTP_404) + |NGX_HTTP_UPSTREAM_FT_HTTP_404 \ + |NGX_HTTP_UPSTREAM_FT_HTTP_429) #define NGX_HTTP_UPSTREAM_INVALID_HEADER 40 From piotrsikora at google.com Wed Oct 19 07:51:44 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 19 Oct 2016 00:51:44 -0700 Subject: [PATCH 2 of 2] HTTP: change default response code when rate-limiting requests In-Reply-To: <1eec5355ef1e4a8b0aec.1476863503@piotrsikora.sfo.corp.google.com> References: <1eec5355ef1e4a8b0aec.1476863503@piotrsikora.sfo.corp.google.com> Message-ID: # HG changeset patch # User Piotr Sikora # Date 1476859163 25200 # Tue Oct 18 23:39:23 2016 -0700 # Node ID cff70893f20b18623ed45c8406050bcf5db78a48 # Parent 1eec5355ef1e4a8b0aecebdec84c744734c0d36e HTTP: change default response code when rate-limiting requests. Previously, "503 Service Unavailable" response code was used, but the new "429 Too Many Requests" response code is more appropriate. Signed-off-by: Piotr Sikora diff -r 1eec5355ef1e -r cff70893f20b src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -712,7 +712,7 @@ ngx_http_limit_req_merge_conf(ngx_conf_t NGX_LOG_INFO : conf->limit_log_level + 1; ngx_conf_merge_uint_value(conf->status_code, prev->status_code, - NGX_HTTP_SERVICE_UNAVAILABLE); + NGX_HTTP_TOO_MANY_REQUESTS); return NGX_CONF_OK; } From vl at nginx.com Wed Oct 19 14:14:33 2016 From: vl at nginx.com (Vladimir Homutov) Date: Wed, 19 Oct 2016 14:14:33 +0000 Subject: [nginx] Core: show file contents only once while dumping configuration. Message-ID: details: http://hg.nginx.org/nginx/rev/1bf4f21b1b72 branches: changeset: 6776:1bf4f21b1b72 user: Vladimir Homutov date: Tue Oct 18 16:33:38 2016 +0300 description: Core: show file contents only once while dumping configuration. Files are considered the same if the path used by nginx during parsing matches. diffstat: src/core/ngx_conf_file.c | 83 ++++++++++++++++++++++++++++++++++------------- src/core/ngx_cycle.c | 3 + src/core/ngx_cycle.h | 4 ++ 3 files changed, 66 insertions(+), 24 deletions(-) diffs (145 lines): diff -r 8081e1f3ab8b -r 1bf4f21b1b72 src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c Tue Oct 18 20:46:06 2016 +0300 +++ b/src/core/ngx_conf_file.c Tue Oct 18 16:33:38 2016 +0300 @@ -10,6 +10,7 @@ #define NGX_CONF_BUFFER 4096 +static ngx_int_t ngx_conf_add_dump(ngx_conf_t *cf, ngx_str_t *filename); static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last); static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf); static void ngx_conf_flush_files(ngx_cycle_t *cycle); @@ -97,17 +98,70 @@ ngx_conf_param(ngx_conf_t *cf) } +static ngx_int_t +ngx_conf_add_dump(ngx_conf_t *cf, ngx_str_t *filename) +{ + off_t size; + u_char *p; + uint32_t hash; + ngx_buf_t *buf; + ngx_str_node_t *sn; + ngx_conf_dump_t *cd; + + hash = ngx_crc32_long(filename->data, filename->len); + + sn = ngx_str_rbtree_lookup(&cf->cycle->config_dump_rbtree, filename, hash); + + if (sn) { + cf->conf_file->dump = NULL; + return NGX_OK; + } + + p = ngx_pstrdup(cf->cycle->pool, filename); + if (p == NULL) { + return NGX_ERROR; + } + + cd = ngx_array_push(&cf->cycle->config_dump); + if (cd == NULL) { + return NGX_ERROR; + } + + size = ngx_file_size(&cf->conf_file->file.info); + + buf = ngx_create_temp_buf(cf->cycle->pool, (size_t) size); + if (buf == NULL) { + return NGX_ERROR; + } + + cd->name.data = p; + cd->name.len = filename->len; + cd->buffer = buf; + + cf->conf_file->dump = buf; + + sn = ngx_palloc(cf->temp_pool, sizeof(ngx_str_node_t)); + if (sn == NULL) { + return NGX_ERROR; + } + + sn->node.key = hash; + sn->str = cd->name; + + ngx_rbtree_insert(&cf->cycle->config_dump_rbtree, &sn->node); + + return NGX_OK; +} + + char * ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) { char *rv; - u_char *p; - off_t size; ngx_fd_t fd; ngx_int_t rc; - ngx_buf_t buf, *tbuf; + ngx_buf_t buf; ngx_conf_file_t *prev, conf_file; - ngx_conf_dump_t *cd; enum { parse_file = 0, parse_block, @@ -167,29 +221,10 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t #endif ) { - p = ngx_pstrdup(cf->cycle->pool, filename); - if (p == NULL) { - goto failed; - } - - size = ngx_file_size(&cf->conf_file->file.info); - - tbuf = ngx_create_temp_buf(cf->cycle->pool, (size_t) size); - if (tbuf == NULL) { + if (ngx_conf_add_dump(cf, filename) != NGX_OK) { goto failed; } - cd = ngx_array_push(&cf->cycle->config_dump); - if (cd == NULL) { - goto failed; - } - - cd->name.len = filename->len; - cd->name.data = p; - cd->buffer = tbuf; - - cf->conf_file->dump = tbuf; - } else { cf->conf_file->dump = NULL; } diff -r 8081e1f3ab8b -r 1bf4f21b1b72 src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Tue Oct 18 20:46:06 2016 +0300 +++ b/src/core/ngx_cycle.c Tue Oct 18 16:33:38 2016 +0300 @@ -132,6 +132,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) return NULL; } + ngx_rbtree_init(&cycle->config_dump_rbtree, &cycle->config_dump_sentinel, + ngx_str_rbtree_insert_value); + if (old_cycle->open_files.part.nelts) { n = old_cycle->open_files.part.nelts; for (part = old_cycle->open_files.part.next; part; part = part->next) { diff -r 8081e1f3ab8b -r 1bf4f21b1b72 src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Tue Oct 18 20:46:06 2016 +0300 +++ b/src/core/ngx_cycle.h Tue Oct 18 16:33:38 2016 +0300 @@ -56,7 +56,11 @@ struct ngx_cycle_s { ngx_array_t listening; ngx_array_t paths; + ngx_array_t config_dump; + ngx_rbtree_t config_dump_rbtree; + ngx_rbtree_node_t config_dump_sentinel; + ngx_list_t open_files; ngx_list_t shared_memory; From mdounin at mdounin.ru Wed Oct 19 16:23:11 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 19 Oct 2016 16:23:11 +0000 Subject: [nginx] SSL: compatibility with BoringSSL. Message-ID: details: http://hg.nginx.org/nginx/rev/563a1ee345a4 branches: changeset: 6777:563a1ee345a4 user: Maxim Dounin date: Wed Oct 19 18:36:50 2016 +0300 description: SSL: compatibility with BoringSSL. BoringSSL changed SSL_set_tlsext_host_name() to be a real function with a (const char *) argument, so it now triggers a warning due to conversion from (u_char *). Added an explicit cast to silence the warning. Prodded by Piotr Sikora, Alessandro Ghedini. diffstat: src/http/ngx_http_upstream.c | 5 ++++- src/stream/ngx_stream_proxy_module.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diffs (28 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 @@ -1696,7 +1696,10 @@ ngx_http_upstream_ssl_name(ngx_http_requ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upstream SSL server name: \"%s\"", name.data); - if (SSL_set_tlsext_host_name(c->ssl->connection, name.data) == 0) { + if (SSL_set_tlsext_host_name(c->ssl->connection, + (char *) name.data) + == 0) + { ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, "SSL_set_tlsext_host_name(\"%s\") failed", name.data); return NGX_ERROR; diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1183,7 +1183,8 @@ ngx_stream_proxy_ssl_name(ngx_stream_ses ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, "upstream SSL server name: \"%s\"", name.data); - if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection, name.data) + if (SSL_set_tlsext_host_name(u->peer.connection->ssl->connection, + (char *) name.data) == 0) { ngx_ssl_error(NGX_LOG_ERR, s->connection->log, 0, From mdounin at mdounin.ru Wed Oct 19 16:31:48 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 19 Oct 2016 19:31:48 +0300 Subject: [PATCH] Upstream: fix warning when building with BoringSSL In-Reply-To: References: <8c3706ffdc9bde38ef50.1475071847@mandy.local> <20161003173822.GF73038@mdounin.ru> Message-ID: <20161019163148.GV73038@mdounin.ru> Hello! On Wed, Oct 19, 2016 at 12:51:30AM -0700, Piotr Sikora wrote: > Hey Maxim, > > > I have no strong objections, but the patch as you've submitted > > casts to "const char *", while just "char *" should be enough. > > While cast to "char *" also works, I must admit that I'm confused as > to why do you prefer to cast to a type that "should be enough" instead > of a type that's expected by the function. The "const char *" function argument essentially says: the argument is of type "char *", and this function will not modify it. So casting to "char *" just casts to an appropriate type, while casting to "const char *" additionally adds a guard that the function used still promises not to modify arguments. Certainly there is no need for such a guard here. Or, from more practical point of view, "char *" works with "const char *" argument, but the opposite is not true. And any change of the function arguments, perhaps unintentional, e.g., if the macro promoted to a function in another library, but without "const" added, will break things. > Anyway, either one is an improvement over current situation, so please commit. Committed, thank you for prodding this. -- Maxim Dounin http://nginx.org/ From vbart at nginx.com Thu Oct 20 13:15:32 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 20 Oct 2016 13:15:32 +0000 Subject: [nginx] HTTP/2: graceful shutdown of active connections (closes #1106). Message-ID: details: http://hg.nginx.org/nginx/rev/5e95b9fb33b7 branches: changeset: 6778:5e95b9fb33b7 user: Valentin Bartenev date: Thu Oct 20 16:15:03 2016 +0300 description: HTTP/2: graceful shutdown of active connections (closes #1106). Previously, while shutting down gracefully, the HTTP/2 connections were closed in transition to idle state after all active streams have been processed. That might never happen if the client continued opening new streams. Now, nginx sends GOAWAY to all HTTP/2 connections and ignores further attempts to open new streams. A worker process will quit as soon as processing of already opened streams is finished. diffstat: src/http/v2/ngx_http_v2.c | 47 ++++++++++++++++++++++++++++++++++++++--------- src/http/v2/ngx_http_v2.h | 1 + 2 files changed, 39 insertions(+), 9 deletions(-) diffs (124 lines): diff -r 563a1ee345a4 -r 5e95b9fb33b7 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Wed Oct 19 18:36:50 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Oct 20 16:15:03 2016 +0300 @@ -136,6 +136,8 @@ static ngx_int_t ngx_http_v2_send_window ngx_uint_t sid, size_t window); static ngx_int_t ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t sid, ngx_uint_t status); +static ngx_int_t ngx_http_v2_send_goaway(ngx_http_v2_connection_t *h2c, + ngx_uint_t status); static ngx_http_v2_out_frame_t *ngx_http_v2_get_frame( ngx_http_v2_connection_t *h2c, size_t length, ngx_uint_t type, @@ -293,6 +295,8 @@ ngx_http_v2_init(ngx_event_t *rev) rev->handler = ngx_http_v2_read_handler; c->write->handler = ngx_http_v2_write_handler; + c->idle = 1; + ngx_http_v2_read_handler(rev); } @@ -320,6 +324,25 @@ ngx_http_v2_read_handler(ngx_event_t *re h2c->blocked = 1; + if (c->close) { + c->close = 0; + h2c->goaway = 1; + + if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) { + ngx_http_v2_finalize_connection(h2c, 0); + return; + } + + if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { + ngx_http_v2_finalize_connection(h2c, 0); + return; + } + + h2c->blocked = 0; + + return; + } + h2mcf = ngx_http_get_module_main_conf(h2c->http_connection->conf_ctx, ngx_http_v2_module); @@ -633,6 +656,11 @@ ngx_http_v2_handle_connection(ngx_http_v /* rc == NGX_OK */ } + if (h2c->goaway) { + ngx_http_close_connection(c); + return; + } + h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, ngx_http_v2_module); if (h2c->state.incomplete) { @@ -640,11 +668,6 @@ ngx_http_v2_handle_connection(ngx_http_v return; } - if (ngx_terminate || ngx_exiting) { - ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR); - return; - } - ngx_destroy_pool(h2c->pool); h2c->pool = NULL; @@ -658,7 +681,6 @@ ngx_http_v2_handle_connection(ngx_http_v #endif c->destroyed = 1; - c->idle = 1; ngx_reusable_connection(c, 1); c->write->handler = ngx_http_empty_handler; @@ -1027,6 +1049,12 @@ ngx_http_v2_state_headers(ngx_http_v2_co return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } + if (h2c->goaway) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "skipping http2 HEADERS frame"); + return ngx_http_v2_state_skip(h2c, pos, end); + } + if ((size_t) (end - pos) < size) { return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_headers); @@ -4162,7 +4190,6 @@ ngx_http_v2_idle_handler(ngx_event_t *re #endif c->destroyed = 0; - c->idle = 0; ngx_reusable_connection(c, 0); h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, @@ -4197,8 +4224,10 @@ ngx_http_v2_finalize_connection(ngx_http h2c->blocked = 1; - if (!c->error && ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) { - (void) ngx_http_v2_send_output_queue(h2c); + if (!c->error && !h2c->goaway) { + if (ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) { + (void) ngx_http_v2_send_output_queue(h2c); + } } c->error = 1; diff -r 563a1ee345a4 -r 5e95b9fb33b7 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Wed Oct 19 18:36:50 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Thu Oct 20 16:15:03 2016 +0300 @@ -146,6 +146,7 @@ struct ngx_http_v2_connection_s { unsigned closed_nodes:8; unsigned settings_ack:1; unsigned blocked:1; + unsigned goaway:1; }; From zelenkov at nginx.com Thu Oct 20 14:18:41 2016 From: zelenkov at nginx.com (Andrey Zelenkov) Date: Thu, 20 Oct 2016 14:18:41 +0000 Subject: [njs] A fix in typeof function. Message-ID: details: http://hg.nginx.org/njs/rev/b290544f11bc branches: changeset: 209:b290544f11bc user: Andrey Zelenkov date: Thu Oct 20 17:12:42 2016 +0300 description: A fix in typeof function. Found with afl-fuzz. diffstat: njs/njs_vm.c | 1 + njs/test/njs_unit_test.c | 3 +++ 2 files changed, 4 insertions(+), 0 deletions(-) diffs (24 lines): diff -r fa9ced8246e5 -r b290544f11bc njs/njs_vm.c --- a/njs/njs_vm.c Tue Oct 18 17:44:01 2016 +0300 +++ b/njs/njs_vm.c Thu Oct 20 17:12:42 2016 +0300 @@ -1444,6 +1444,7 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_valu &njs_string_object, &njs_string_function, &njs_string_object, + &njs_string_object, }; vm->retval = *types[value->type]; diff -r fa9ced8246e5 -r b290544f11bc njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 18 17:44:01 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Oct 20 17:12:42 2016 +0300 @@ -1795,6 +1795,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("typeof /./i"), nxt_string("object") }, + { nxt_string("typeof Date.prototype"), + nxt_string("object") }, + { nxt_string("typeof a"), nxt_string("undefined") }, From hongzhidao at gmail.com Fri Oct 21 03:44:01 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Fri, 21 Oct 2016 11:44:01 +0800 Subject: [nginx-test] tempdir permission Message-ID: Hi! I run the following test. > cat test.t #!/usr/bin/perl use warnings; use strict; use File::Temp qw/ tempdir /; tempdir( 'nginx-test-XXXXXXXXXX', TMPDIR => 1 ) or die "Can't create temp directory: $!\n"; > prove test.t > ll -d /tmp/nginx-test* drwx------ 2 root root 4096 Oct 20 06:09 /tmp/nginx-test-8ZmZ2FksyP The same problem is exist in nginx-test. And I can't pass the test like request_id.t. sub new { my $self = {}; bless $self; $self->{_pid} = $$; $self->{_alerts} = 1; $self->{_testdir} = tempdir( 'nginx-test-XXXXXXXXXX', TMPDIR => 1 ) or die "Can't create temp directory: $!\n"; + chmod 0755, $self->{_testdir}; # Should I change permission here??? $self->{_testdir} =~ s!\\!/!g if $^O eq 'MSWin32'; mkdir "$self->{_testdir}/logs" or die "Can't create logs directory: $!\n"; Test::More::BAIL_OUT("no $NGINX binary found") unless -x $NGINX; return $self; } B.R~ -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Fri Oct 21 12:19:35 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 21 Oct 2016 12:19:35 +0000 Subject: [nginx] Image filter: support for WebP. Message-ID: details: http://hg.nginx.org/nginx/rev/e4b00a021cea branches: changeset: 6779:e4b00a021cea user: Valentin Bartenev date: Fri Oct 21 15:18:44 2016 +0300 description: Image filter: support for WebP. In collaboration with Ivan Poluyanov. diffstat: auto/lib/libgd/conf | 5 + src/http/modules/ngx_http_image_filter_module.c | 164 +++++++++++++++++++++++- 2 files changed, 164 insertions(+), 5 deletions(-) diffs (295 lines): diff -r 5e95b9fb33b7 -r e4b00a021cea auto/lib/libgd/conf --- a/auto/lib/libgd/conf Thu Oct 20 16:15:03 2016 +0300 +++ b/auto/lib/libgd/conf Fri Oct 21 15:18:44 2016 +0300 @@ -74,6 +74,11 @@ if [ $ngx_found = yes ]; then NGX_LIB_LIBGD=$ngx_feature_libs + ngx_feature="GD WebP support" + ngx_feature_name="NGX_HAVE_GD_WEBP" + ngx_feature_test="gdImagePtr img = gdImageCreateFromWebpPtr(1, NULL);" + . auto/feature + else cat << END diff -r 5e95b9fb33b7 -r e4b00a021cea src/http/modules/ngx_http_image_filter_module.c --- a/src/http/modules/ngx_http_image_filter_module.c Thu Oct 20 16:15:03 2016 +0300 +++ b/src/http/modules/ngx_http_image_filter_module.c Fri Oct 21 15:18:44 2016 +0300 @@ -31,6 +31,7 @@ #define NGX_HTTP_IMAGE_JPEG 1 #define NGX_HTTP_IMAGE_GIF 2 #define NGX_HTTP_IMAGE_PNG 3 +#define NGX_HTTP_IMAGE_WEBP 4 #define NGX_HTTP_IMAGE_BUFFERED 0x08 @@ -42,6 +43,7 @@ typedef struct { ngx_uint_t height; ngx_uint_t angle; ngx_uint_t jpeg_quality; + ngx_uint_t webp_quality; ngx_uint_t sharpen; ngx_flag_t transparency; @@ -51,6 +53,7 @@ typedef struct { ngx_http_complex_value_t *hcv; ngx_http_complex_value_t *acv; ngx_http_complex_value_t *jqcv; + ngx_http_complex_value_t *wqcv; ngx_http_complex_value_t *shcv; size_t buffer_size; @@ -109,6 +112,8 @@ static char *ngx_http_image_filter(ngx_c void *conf); static char *ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_image_filter_webp_quality(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf); static char *ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf); @@ -130,6 +135,13 @@ static ngx_command_t ngx_http_image_fil 0, NULL }, + { ngx_string("image_filter_webp_quality"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_image_filter_webp_quality, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + { ngx_string("image_filter_sharpen"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_image_filter_sharpen, @@ -200,7 +212,8 @@ static ngx_http_output_body_filter_pt static ngx_str_t ngx_http_image_types[] = { ngx_string("image/jpeg"), ngx_string("image/gif"), - ngx_string("image/png") + ngx_string("image/png"), + ngx_string("image/webp") }; @@ -441,6 +454,13 @@ ngx_http_image_test(ngx_http_request_t * /* PNG */ return NGX_HTTP_IMAGE_PNG; + + } else if (p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F' + && p[8] == 'W' && p[9] == 'E' && p[10] == 'B' && p[11] == 'P') + { + /* WebP */ + + return NGX_HTTP_IMAGE_WEBP; } return NGX_HTTP_IMAGE_NONE; @@ -731,6 +751,56 @@ ngx_http_image_size(ngx_http_request_t * break; + case NGX_HTTP_IMAGE_WEBP: + + if (ctx->length < 30) { + return NGX_DECLINED; + } + + if (p[12] != 'V' || p[13] != 'P' || p[14] != '8') { + return NGX_DECLINED; + } + + switch (p[15]) { + + case ' ': + if (p[20] & 1) { + /* not a key frame */ + return NGX_DECLINED; + } + + if (p[23] != 0x9d || p[24] != 0x01 || p[25] != 0x2a) { + /* invalid start code */ + return NGX_DECLINED; + } + + width = (p[26] | p[27] << 8) & 0x3fff; + height = (p[28] | p[29] << 8) & 0x3fff; + + break; + + case 'L': + if (p[20] != 0x2f) { + /* invalid signature */ + return NGX_DECLINED; + } + + width = ((p[21] | p[22] << 8) & 0x3fff) + 1; + height = ((p[22] >> 6 | p[23] << 2 | p[24] << 10) & 0x3fff) + 1; + + break; + + case 'X': + width = (p[24] | p[25] << 8 | p[26] << 16) + 1; + height = (p[27] | p[28] << 8 | p[29] << 16) + 1; + break; + + default: + return NGX_DECLINED; + } + + break; + default: return NGX_DECLINED; @@ -1043,6 +1113,15 @@ ngx_http_image_source(ngx_http_request_t failed = "gdImageCreateFromPngPtr() failed"; break; + case NGX_HTTP_IMAGE_WEBP: +#if (NGX_HAVE_GD_WEBP) + img = gdImageCreateFromWebpPtr(ctx->length, ctx->image); + failed = "gdImageCreateFromWebpPtr() failed"; +#else + failed = "nginx was built without GD WebP support"; +#endif + break; + default: failed = "unknown image type"; break; @@ -1090,7 +1169,7 @@ ngx_http_image_out(ngx_http_request_t *r { char *failed; u_char *out; - ngx_int_t jq; + ngx_int_t q; ngx_http_image_filter_conf_t *conf; out = NULL; @@ -1100,12 +1179,12 @@ ngx_http_image_out(ngx_http_request_t *r case NGX_HTTP_IMAGE_JPEG: conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); - jq = ngx_http_image_filter_get_value(r, conf->jqcv, conf->jpeg_quality); - if (jq <= 0) { + q = ngx_http_image_filter_get_value(r, conf->jqcv, conf->jpeg_quality); + if (q <= 0) { return NULL; } - out = gdImageJpegPtr(img, size, jq); + out = gdImageJpegPtr(img, size, q); failed = "gdImageJpegPtr() failed"; break; @@ -1119,6 +1198,22 @@ ngx_http_image_out(ngx_http_request_t *r failed = "gdImagePngPtr() failed"; break; + case NGX_HTTP_IMAGE_WEBP: +#if (NGX_HAVE_GD_WEBP) + conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); + + q = ngx_http_image_filter_get_value(r, conf->wqcv, conf->webp_quality); + if (q <= 0) { + return NULL; + } + + out = gdImageWebpPtrEx(img, size, q); + failed = "gdImageWebpPtrEx() failed"; +#else + failed = "nginx was built without GD WebP support"; +#endif + break; + default: failed = "unknown image type"; break; @@ -1196,11 +1291,13 @@ ngx_http_image_filter_create_conf(ngx_co * conf->hcv = NULL; * conf->acv = NULL; * conf->jqcv = NULL; + * conf->wqcv = NULL; * conf->shcv = NULL; */ conf->filter = NGX_CONF_UNSET_UINT; conf->jpeg_quality = NGX_CONF_UNSET_UINT; + conf->webp_quality = NGX_CONF_UNSET_UINT; conf->sharpen = NGX_CONF_UNSET_UINT; conf->transparency = NGX_CONF_UNSET; conf->interlace = NGX_CONF_UNSET; @@ -1242,6 +1339,16 @@ ngx_http_image_filter_merge_conf(ngx_con } } + if (conf->webp_quality == NGX_CONF_UNSET_UINT) { + + /* 80 is libwebp default quality */ + ngx_conf_merge_uint_value(conf->webp_quality, prev->webp_quality, 80); + + if (conf->wqcv == NULL) { + conf->wqcv = prev->wqcv; + } + } + if (conf->sharpen == NGX_CONF_UNSET_UINT) { ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0); @@ -1462,6 +1569,53 @@ ngx_http_image_filter_jpeg_quality(ngx_c static char * +ngx_http_image_filter_webp_quality(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ + ngx_http_image_filter_conf_t *imcf = conf; + + ngx_str_t *value; + ngx_int_t n; + ngx_http_complex_value_t cv; + ngx_http_compile_complex_value_t ccv; + + value = cf->args->elts; + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &cv; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + if (cv.lengths == NULL) { + n = ngx_http_image_filter_value(&value[1]); + + if (n <= 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid value \"%V\"", &value[1]); + return NGX_CONF_ERROR; + } + + imcf->webp_quality = (ngx_uint_t) n; + + } else { + imcf->wqcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); + if (imcf->wqcv == NULL) { + return NGX_CONF_ERROR; + } + + *imcf->wqcv = cv; + } + + return NGX_CONF_OK; +} + + +static char * ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { From mdounin at mdounin.ru Fri Oct 21 13:04:55 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 21 Oct 2016 16:04:55 +0300 Subject: [nginx-test] tempdir permission In-Reply-To: References: Message-ID: <20161021130455.GH73038@mdounin.ru> Hello! On Fri, Oct 21, 2016 at 11:44:01AM +0800, ??? wrote: > Hi! > > I run the following test. > > > cat test.t > #!/usr/bin/perl > > use warnings; > use strict; > > use File::Temp qw/ tempdir /; > > tempdir( > 'nginx-test-XXXXXXXXXX', > TMPDIR => 1 > ) > or die "Can't create temp directory: $!\n"; > > > > prove test.t > > > > ll -d /tmp/nginx-test* > drwx------ 2 root root 4096 Oct 20 06:09 /tmp/nginx-test-8ZmZ2FksyP > > > The same problem is exist in nginx-test. And I can't pass the test like > request_id.t. Start tests under unprivileged user, not under root. -- Maxim Dounin http://nginx.org/ From xeioex at nginx.com Fri Oct 21 13:47:46 2016 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Fri, 21 Oct 2016 13:47:46 +0000 Subject: [nginx] SSL: RFC2253 compliant $ssl_client_s_dn and $ssl_client_i_dn. Message-ID: details: http://hg.nginx.org/nginx/rev/56d6bfe6b609 branches: changeset: 6780:56d6bfe6b609 user: Dmitry Volyntsev date: Fri Oct 21 16:28:39 2016 +0300 description: SSL: RFC2253 compliant $ssl_client_s_dn and $ssl_client_i_dn. Originally, the variables kept a result of X509_NAME_oneline(), which is, according to the official documentation, a legacy function. It produces a non standard output form and has various quirks and inconsistencies. The RFC2253 compliant behavior is introduced for these variables. The original variables are available through $ssl_client_s_dn_legacy and $ssl_client_i_dn_legacy. diffstat: src/event/ngx_event_openssl.c | 106 ++++++++++++++++++++++++++++++++- src/event/ngx_event_openssl.h | 4 + src/http/modules/ngx_http_ssl_module.c | 6 + 3 files changed, 115 insertions(+), 1 deletions(-) diffs (153 lines): diff -r e4b00a021cea -r 56d6bfe6b609 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Fri Oct 21 15:18:44 2016 +0300 +++ b/src/event/ngx_event_openssl.c Fri Oct 21 16:28:39 2016 +0300 @@ -3438,6 +3438,109 @@ ngx_ssl_get_certificate(ngx_connection_t ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { + BIO *bio; + X509 *cert; + X509_NAME *name; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + + name = X509_get_subject_name(cert); + if (name == NULL) { + return NGX_ERROR; + } + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + X509_free(cert); + return NGX_ERROR; + } + + if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) { + goto failed; + } + + s->len = BIO_pending(bio); + s->data = ngx_pnalloc(pool, s->len); + if (s->data == NULL) { + goto failed; + } + + BIO_read(bio, s->data, s->len); + + BIO_free(bio); + X509_free(cert); + + return NGX_OK; + +failed: + + BIO_free(bio); + X509_free(cert); + + return NGX_ERROR; +} + + +ngx_int_t +ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ + BIO *bio; + X509 *cert; + X509_NAME *name; + + s->len = 0; + + cert = SSL_get_peer_certificate(c->ssl->connection); + if (cert == NULL) { + return NGX_OK; + } + + name = X509_get_issuer_name(cert); + if (name == NULL) { + return NGX_ERROR; + } + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + X509_free(cert); + return NGX_ERROR; + } + + if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) { + goto failed; + } + + s->len = BIO_pending(bio); + s->data = ngx_pnalloc(pool, s->len); + if (s->data == NULL) { + goto failed; + } + + BIO_read(bio, s->data, s->len); + + BIO_free(bio); + X509_free(cert); + + return NGX_OK; + +failed: + + BIO_free(bio); + X509_free(cert); + + return NGX_ERROR; +} + + +ngx_int_t +ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s) +{ char *p; size_t len; X509 *cert; @@ -3478,7 +3581,8 @@ ngx_ssl_get_subject_dn(ngx_connection_t ngx_int_t -ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s) { char *p; size_t len; diff -r e4b00a021cea -r 56d6bfe6b609 src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Fri Oct 21 15:18:44 2016 +0300 +++ b/src/event/ngx_event_openssl.h Fri Oct 21 16:28:39 2016 +0300 @@ -205,6 +205,10 @@ ngx_int_t ngx_ssl_get_subject_dn(ngx_con ngx_str_t *s); ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); +ngx_int_t ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, diff -r e4b00a021cea -r 56d6bfe6b609 src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c Fri Oct 21 15:18:44 2016 +0300 +++ b/src/http/modules/ngx_http_ssl_module.c Fri Oct 21 16:28:39 2016 +0300 @@ -298,6 +298,12 @@ static ngx_http_variable_t ngx_http_ssl { ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_s_dn_legacy"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_subject_dn_legacy, NGX_HTTP_VAR_CHANGEABLE, 0 }, + + { ngx_string("ssl_client_i_dn_legacy"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_issuer_dn_legacy, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 }, From hongzhidao at gmail.com Fri Oct 21 14:33:05 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Fri, 21 Oct 2016 22:33:05 +0800 Subject: [nginx-test] tempdir permission In-Reply-To: <20161021130455.GH73038@mdounin.ru> References: <20161021130455.GH73038@mdounin.ru> Message-ID: Ok, thanks. 2016-10-21 21:04 GMT+08:00 Maxim Dounin : > Hello! > > On Fri, Oct 21, 2016 at 11:44:01AM +0800, ??? wrote: > > > Hi! > > > > I run the following test. > > > > > cat test.t > > #!/usr/bin/perl > > > > use warnings; > > use strict; > > > > use File::Temp qw/ tempdir /; > > > > tempdir( > > 'nginx-test-XXXXXXXXXX', > > TMPDIR => 1 > > ) > > or die "Can't create temp directory: $!\n"; > > > > > > > prove test.t > > > > > > > ll -d /tmp/nginx-test* > > drwx------ 2 root root 4096 Oct 20 06:09 /tmp/nginx-test-8ZmZ2FksyP > > > > > > The same problem is exist in nginx-test. And I can't pass the test like > > request_id.t. > > Start tests under unprivileged user, not under root. > > -- > 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 math.vachon at gmail.com Fri Oct 21 15:17:40 2016 From: math.vachon at gmail.com (Mathieu Vachon) Date: Fri, 21 Oct 2016 11:17:40 -0400 Subject: string duplicate Message-ID: Hi there, Despite reading the api manual, i cant seem to find a function to duplicate a ngx_str_t to another. Did i miss it , or have to roll my own duplicate stuff ? -Mathieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From vbart at nginx.com Fri Oct 21 15:26:19 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Fri, 21 Oct 2016 18:26:19 +0300 Subject: string duplicate In-Reply-To: References: Message-ID: <2567649.TLcSeAVkNK@vbart-workstation> On Friday 21 October 2016 11:17:40 Mathieu Vachon wrote: > Hi there, > > Despite reading the api manual, i cant seem to find a function to duplicate > a ngx_str_t to another. > > Did i miss it , or have to roll my own duplicate stuff ? > ngx_pstrdup()? wbr, Valentin V. Bartenev From math.vachon at gmail.com Fri Oct 21 15:31:31 2016 From: math.vachon at gmail.com (Mathieu Vachon) Date: Fri, 21 Oct 2016 11:31:31 -0400 Subject: string duplicate In-Reply-To: <2567649.TLcSeAVkNK@vbart-workstation> References: <2567649.TLcSeAVkNK@vbart-workstation> Message-ID: I found this on the web : static ngx_str_t* ngx_http_uploadprogress_strdup(ngx_str_t *src, ngx_log_t * log) { ngx_str_t *dst; dst = ngx_alloc(src->len + sizeof(ngx_str_t), log); if (dst == NULL) { return NULL; } dst->len = src->len; ngx_memcpy(((char*)dst + sizeof(ngx_str_t)) , src->data, src->len); dst->data = ((u_char*)dst + sizeof(ngx_str_t)); return dst; } Was wondering if there was smthg in the api that would achieve the same thing. Thx for the ngx_pstrdup() suggestion I've look at it , but didnt want to go all the way with the pool etc . On Fri, Oct 21, 2016 at 11:26 AM, Valentin V. Bartenev wrote: > On Friday 21 October 2016 11:17:40 Mathieu Vachon wrote: > > Hi there, > > > > Despite reading the api manual, i cant seem to find a function to > duplicate > > a ngx_str_t to another. > > > > Did i miss it , or have to roll my own duplicate stuff ? > > > > ngx_pstrdup()? > > 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 dilaz03 at gmail.com Fri Oct 21 19:57:18 2016 From: dilaz03 at gmail.com (Dmitry Lazurkin) Date: Fri, 21 Oct 2016 22:57:18 +0300 Subject: [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: Message-ID: <944b0780-5665-728e-be18-43a7b195a654@gmail.com> Ticket on issue tracker with my comment: https://trac.nginx.org/nginx/ticket/283 From igor at sysoev.ru Fri Oct 21 20:05:31 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 21 Oct 2016 20:05:31 +0000 Subject: [njs] A fix in Array.prototype.splice() function. Message-ID: details: http://hg.nginx.org/njs/rev/7685bf403554 branches: changeset: 210:7685bf403554 user: Igor Sysoev date: Fri Oct 21 23:03:02 2016 +0300 description: A fix in Array.prototype.splice() function. Found with afl-fuzz. diffstat: njs/njs_array.c | 39 ++++++++++++++++++++++++++++----------- njs/test/njs_unit_test.c | 9 +++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) diffs (97 lines): diff -r b290544f11bc -r 7685bf403554 njs/njs_array.c --- a/njs/njs_array.c Thu Oct 20 17:12:42 2016 +0300 +++ b/njs/njs_array.c Fri Oct 21 23:03:02 2016 +0300 @@ -574,8 +574,8 @@ njs_array_prototype_splice(njs_vm_t *vm, njs_index_t unused) { njs_ret_t ret; - nxt_int_t items, delta; - nxt_uint_t i, n, start, delete, length; + nxt_int_t n, start, length, items, delta, delete; + nxt_uint_t i; njs_array_t *array, *deleted; array = NULL; @@ -584,19 +584,33 @@ njs_array_prototype_splice(njs_vm_t *vm, if (njs_is_array(&args[0])) { array = args[0].data.u.array; + length = array->length; if (nargs > 1) { start = args[1].data.u.number; - if (start > array->length) { - start = array->length; + if (start < 0) { + start += length; + + if (start < 0) { + start = 0; + } + + } else if (start > length) { + start = length; } + delete = length - start; + if (nargs > 2) { - delete = args[2].data.u.number; + n = args[2].data.u.number; - } else { - delete = array->length - start; + if (n < 0) { + delete = 0; + + } else if (n < delete) { + delete = n; + } } } } @@ -606,17 +620,20 @@ njs_array_prototype_splice(njs_vm_t *vm, return NXT_ERROR; } - if (array != NULL && (delete != 0 || nargs > 3)) { - length = array->length; + if (array != NULL && (delete >= 0 || nargs > 3)) { /* Move deleted items to a new array to return. */ - for (i = 0, n = start; i < delete && n < length; i++, n++) { + for (i = 0, n = start; i < (nxt_uint_t) delete; i++, n++) { /* No retention required. */ deleted->start[i] = array->start[n]; } items = nargs - 3; - items = items >= 0 ? items : 0; + + if (items < 0) { + items = 0; + } + delta = items - delete; if (delta != 0) { diff -r b290544f11bc -r 7685bf403554 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Oct 20 17:12:42 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Oct 21 23:03:02 2016 +0300 @@ -2316,6 +2316,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = []; a.splice()"), nxt_string("") }, + { nxt_string("[].splice(0,5,0)"), + nxt_string("") }, + + { nxt_string("[1,2,3,4,5].splice(-2,3,0)"), + nxt_string("4,5") }, + + { nxt_string("[].__proto__.splice(0,1,0)"), + nxt_string("") }, + { nxt_string("var a = [];" "a.splice(9,0,1,2).join(':') + '|' + a"), nxt_string("|1,2") }, From dilaz03 at gmail.com Fri Oct 21 20:52:02 2016 From: dilaz03 at gmail.com (Dmitry Lazurkin) Date: Fri, 21 Oct 2016 23:52:02 +0300 Subject: [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: Message-ID: Hello, I refactor solution with ngx_http_set_complex_value_slot. # HG changeset patch # User Dmitry Lazurkin # Date 1476631441 -10800 # Sun Oct 16 18:24:01 2016 +0300 # Node ID 9fbfc0ccb28e1eee624ff212de88fa1c051f09d9 # Parent 56d6bfe6b609c565a9f500bde573fd9b488ff960 Proxy: support variables for proxy_method directive. diff -r 56d6bfe6b609 -r 9fbfc0ccb28e src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Fri Oct 21 16:28:39 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Sun Oct 16 18:24:01 2016 +0300 @@ -73,7 +73,7 @@ ngx_array_t *cookie_domains; ngx_array_t *cookie_paths; - ngx_str_t method; + ngx_http_complex_value_t *method; ngx_str_t location; ngx_str_t url; @@ -380,7 +380,7 @@ { ngx_string("proxy_method"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_http_set_complex_value_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, method), NULL }, @@ -1159,8 +1159,10 @@ /* HEAD was changed to GET to cache response */ method = u->method; - } else if (plcf->method.len) { - method = plcf->method; + } else if (plcf->method != NULL) { + if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) { + return NGX_ERROR; + } } else { method = r->method_name; @@ -3158,7 +3160,9 @@ #endif - ngx_conf_merge_str_value(conf->method, prev->method, ""); + if (conf->method == NULL) { + conf->method = prev->method; + } ngx_conf_merge_value(conf->upstream.pass_request_headers, prev->upstream.pass_request_headers, 1); From dilaz03 at gmail.com Fri Oct 21 20:53:11 2016 From: dilaz03 at gmail.com (Dmitry Lazurkin) Date: Fri, 21 Oct 2016 23:53:11 +0300 Subject: [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: Message-ID: <6f0d1849-460d-e2a7-1d1e-b96143e5f9f1@gmail.com> Add more tests. # HG changeset patch # User Dmitry Lazurkin # Date 1476632999 -10800 # Sun Oct 16 18:49:59 2016 +0300 # Node ID 916ac83eed31a4e7f6f303e28867b925fc62bc27 # Parent 1b11a12be17913a75e81d318dcb6b912eac5f29e Tests: add tests for proxy_method directive. diff -r 1b11a12be179 -r 916ac83eed31 proxy_method.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/proxy_method.t Sun Oct 16 18:49:59 2016 +0300 @@ -0,0 +1,86 @@ +#!/usr/bin/perl + +# (C) Dmitry Lazurkin + +# Tests for proxy_method. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(4) + ->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; + +events { +} + +http { + %%TEST_GLOBALS_HTTP%% + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /preserve { + proxy_pass http://127.0.0.1:8080/get-method; + } + + location /const { + proxy_pass http://127.0.0.1:8080/get-method; + proxy_method POST; + } + + location /var { + proxy_pass http://127.0.0.1:8080/get-method; + proxy_method $arg_method; + } + + location /parent { + proxy_method POST; + location /parent/child { + proxy_pass http://127.0.0.1:8080/get-method; + } + } + + location /get-method { + return 200 "request_method=$request_method"; + } + } +} + +EOF + +$t->run(); + +############################################################################### + +like(http_get('/preserve'), qr/request_method=GET/, + 'proxy_method from request'); + +like(http_get('/const'), qr/request_method=POST/, + 'proxy_method from constant'); + +like(http_get('/var?method=POST'), qr/request_method=POST/, + 'proxy_method from variable'); + +like(http_get('/parent/child'), qr/request_method=POST/, + 'proxy_method from parent'); + +############################################################################### From dilaz03 at gmail.com Fri Oct 21 21:10:07 2016 From: dilaz03 at gmail.com (Dmitry Lazurkin) Date: Sat, 22 Oct 2016 00:10:07 +0300 Subject: [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: Message-ID: <41dc35ff-49c1-afde-81b6-a17d7bc0fda5@gmail.com> Formatting of previous patch was corrupted. Sorry for another message. I don't known how to correct work with mailing list. I try to set fixed width for patch. # HG changeset patch # User Dmitry Lazurkin # Date 1476631441 -10800 # Sun Oct 16 18:24:01 2016 +0300 # Node ID 9fbfc0ccb28e1eee624ff212de88fa1c051f09d9 # Parent 56d6bfe6b609c565a9f500bde573fd9b488ff960 Proxy: support variables for proxy_method directive. diff -r 56d6bfe6b609 -r 9fbfc0ccb28e src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Fri Oct 21 16:28:39 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Sun Oct 16 18:24:01 2016 +0300 @@ -73,7 +73,7 @@ ngx_array_t *cookie_domains; ngx_array_t *cookie_paths; - ngx_str_t method; + ngx_http_complex_value_t *method; ngx_str_t location; ngx_str_t url; @@ -380,7 +380,7 @@ { ngx_string("proxy_method"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_http_set_complex_value_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, method), NULL }, @@ -1159,8 +1159,10 @@ /* HEAD was changed to GET to cache response */ method = u->method; - } else if (plcf->method.len) { - method = plcf->method; + } else if (plcf->method != NULL) { + if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) { + return NGX_ERROR; + } } else { method = r->method_name; @@ -3158,7 +3160,9 @@ #endif - ngx_conf_merge_str_value(conf->method, prev->method, ""); + if (conf->method == NULL) { + conf->method = prev->method; + } ngx_conf_merge_value(conf->upstream.pass_request_headers, prev->upstream.pass_request_headers, 1); From dilaz03 at gmail.com Fri Oct 21 21:31:16 2016 From: dilaz03 at gmail.com (dilaz03 at gmail.com) Date: Sat, 22 Oct 2016 00:31:16 +0300 Subject: [PATCH] [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: <41dc35ff-49c1-afde-81b6-a17d7bc0fda5@gmail.com> References: <41dc35ff-49c1-afde-81b6-a17d7bc0fda5@gmail.com> Message-ID: <9fbfc0ccb28e1eee624f.1477085476@user-notebook> # HG changeset patch # User Dmitry Lazurkin # Date 1476631441 -10800 # Sun Oct 16 18:24:01 2016 +0300 # Node ID 9fbfc0ccb28e1eee624ff212de88fa1c051f09d9 # Parent 56d6bfe6b609c565a9f500bde573fd9b488ff960 Proxy: support variables for proxy_method directive. diff -r 56d6bfe6b609 -r 9fbfc0ccb28e src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Fri Oct 21 16:28:39 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Sun Oct 16 18:24:01 2016 +0300 @@ -73,7 +73,7 @@ ngx_array_t *cookie_domains; ngx_array_t *cookie_paths; - ngx_str_t method; + ngx_http_complex_value_t *method; ngx_str_t location; ngx_str_t url; @@ -380,7 +380,7 @@ { ngx_string("proxy_method"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_http_set_complex_value_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, method), NULL }, @@ -1159,8 +1159,10 @@ /* HEAD was changed to GET to cache response */ method = u->method; - } else if (plcf->method.len) { - method = plcf->method; + } else if (plcf->method != NULL) { + if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) { + return NGX_ERROR; + } } else { method = r->method_name; @@ -3158,7 +3160,9 @@ #endif - ngx_conf_merge_str_value(conf->method, prev->method, ""); + if (conf->method == NULL) { + conf->method = prev->method; + } ngx_conf_merge_value(conf->upstream.pass_request_headers, prev->upstream.pass_request_headers, 1); From math.vachon at gmail.com Fri Oct 21 22:27:55 2016 From: math.vachon at gmail.com (Mathieu Vachon) Date: Fri, 21 Oct 2016 18:27:55 -0400 Subject: wirte_event_handler Message-ID: Hello again, I was wondering what would be the best approach to get a callback @ the termination of a request ? r->write_event_handler ? and simply call ngx_http_finalize_request(r, 0) after ? -Mathieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Mon Oct 24 11:44:38 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 24 Oct 2016 14:44:38 +0300 Subject: wirte_event_handler In-Reply-To: References: Message-ID: <20161024114437.GJ73038@mdounin.ru> Hello! On Fri, Oct 21, 2016 at 06:27:55PM -0400, Mathieu Vachon wrote: > Hello again, > > I was wondering what would be the best approach to get a callback @ the > termination of a request ? > > r->write_event_handler ? and simply call ngx_http_finalize_request(r, 0) > after ? Adding a pool cleanup handler to the request pool should be correct solution. -- Maxim Dounin http://nginx.org/ From igor at sysoev.ru Mon Oct 24 12:03:49 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 12:03:49 +0000 Subject: [njs] A fix in decodeURI() and decodeURIComponent() functions. Message-ID: details: http://hg.nginx.org/njs/rev/cec366d97854 branches: changeset: 211:cec366d97854 user: Igor Sysoev date: Sat Oct 22 20:24:32 2016 +0300 description: A fix in decodeURI() and decodeURIComponent() functions. Found with afl-fuzz. diffstat: njs/njs_string.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diffs (36 lines): diff -r 7685bf403554 -r cec366d97854 njs/njs_string.c --- a/njs/njs_string.c Fri Oct 21 23:03:02 2016 +0300 +++ b/njs/njs_string.c Sat Oct 22 20:24:32 2016 +0300 @@ -3070,7 +3070,6 @@ njs_string_decode(njs_vm_t *vm, njs_valu byte = *src++; if (byte == '%') { - size -= 2; if (size <= 0) { @@ -3117,6 +3116,8 @@ njs_string_decode(njs_vm_t *vm, njs_valu byte = *src++; if (byte == '%') { + size -= 2; + d0 = hex[*src++]; d1 = hex[*src++]; byte = (d0 << 4) + d1; @@ -3124,7 +3125,6 @@ njs_string_decode(njs_vm_t *vm, njs_valu utf8 |= (byte >= 0x80); if ((reserve[byte >> 5] & ((uint32_t) 1 << (byte & 0x1f))) != 0) { - size -= 2; *dst++ = '%'; *dst++ = src[-2]; byte = src[-1]; @@ -3132,7 +3132,6 @@ njs_string_decode(njs_vm_t *vm, njs_valu } *dst++ = byte; - size--; } while (size != 0); From igor at sysoev.ru Mon Oct 24 12:03:50 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 12:03:50 +0000 Subject: [njs] Array creation and reallocation optimizations. Message-ID: details: http://hg.nginx.org/njs/rev/bf848210269c branches: changeset: 212:bf848210269c user: Igor Sysoev date: Mon Oct 24 14:12:12 2016 +0300 description: Array creation and reallocation optimizations. diffstat: njs/njs_array.c | 35 ++++++++++------------------------- njs/njs_disassembler.c | 5 +++-- njs/njs_generator.c | 6 +----- njs/njs_parser.c | 5 +++-- njs/njs_vm.c | 41 ++++++++++++++++++++++++++++++----------- 5 files changed, 47 insertions(+), 45 deletions(-) diffs (213 lines): diff -r cec366d97854 -r bf848210269c njs/njs_array.c --- a/njs/njs_array.c Sat Oct 22 20:24:32 2016 +0300 +++ b/njs/njs_array.c Mon Oct 24 14:12:12 2016 +0300 @@ -184,8 +184,7 @@ njs_ret_t njs_array_realloc(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, uint32_t size) { - nxt_uint_t n; - njs_value_t *value, *old; + njs_value_t *start, *old; if (size != array->size) { if (size < 16) { @@ -196,35 +195,21 @@ njs_array_realloc(njs_vm_t *vm, njs_arra } } - value = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), + start = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), (prepend + size) * sizeof(njs_value_t)); - if (nxt_slow_path(value == NULL)) { + if (nxt_slow_path(start == NULL)) { return NXT_ERROR; } - old = array->data; - array->data = value; - - while (prepend != 0) { - njs_set_invalid(value); - value++; - prepend--; - } - - memcpy(value, array->start, array->size * sizeof(njs_value_t)); - - array->start = value; - n = array->size; array->size = size; - value += n; - size -= n; + old = array->data; + array->data = start; + start += prepend; - while (size != 0) { - njs_set_invalid(value); - value++; - size--; - } + memcpy(start, array->start, array->length * sizeof(njs_value_t)); + + array->start = start; nxt_mem_cache_free(vm->mem_cache_pool, old); @@ -515,7 +500,7 @@ njs_array_prototype_unshift(njs_vm_t *vm if (n != 0) { if ((intptr_t) n > (array->start - array->data)) { - ret = njs_array_realloc(vm, array, n, array->size); + ret = njs_array_realloc(vm, array, n, 0); if (nxt_slow_path(ret != NXT_OK)) { return ret; } diff -r cec366d97854 -r bf848210269c njs/njs_disassembler.c --- a/njs/njs_disassembler.c Sat Oct 22 20:24:32 2016 +0300 +++ b/njs/njs_disassembler.c Mon Oct 24 14:12:12 2016 +0300 @@ -197,8 +197,9 @@ njs_disassemble(u_char *start, u_char *e if (operation == njs_vmcode_array) { array = (njs_vmcode_array_t *) p; - printf("%05zd ARRAY %04zX %zd\n", - p - start, (size_t) array->retval, (size_t) array->length); + printf("%05zd ARRAY %04zX %zd%s\n", + p - start, (size_t) array->retval, (size_t) array->length, + array->code.ctor ? " INIT" : ""); p += sizeof(njs_vmcode_array_t); diff -r cec366d97854 -r bf848210269c njs/njs_generator.c --- a/njs/njs_generator.c Sat Oct 22 20:24:32 2016 +0300 +++ b/njs/njs_generator.c Mon Oct 24 14:12:12 2016 +0300 @@ -1510,15 +1510,11 @@ njs_generate_array(njs_vm_t *vm, njs_par array->code.operation = njs_vmcode_array; array->code.operands = NJS_VMCODE_1OPERAND; array->code.retval = NJS_VMCODE_RETVAL; + array->code.ctor = node->ctor; array->retval = node->index; array->length = node->u.length; - if (node->left == NULL) { - return NXT_OK; - } - /* Initialize array. */ - return njs_generator(vm, parser, node->left); } diff -r cec366d97854 -r bf848210269c njs/njs_parser.c --- a/njs/njs_parser.c Sat Oct 22 20:24:32 2016 +0300 +++ b/njs/njs_parser.c Mon Oct 24 14:12:12 2016 +0300 @@ -1885,6 +1885,7 @@ njs_parser_array(njs_vm_t *vm, njs_parse } if (token == NJS_TOKEN_COMMA) { + obj->ctor = 1; index++; continue; } @@ -1942,11 +1943,11 @@ njs_parser_array(njs_vm_t *vm, njs_parse stmt->left = left; stmt->right = assign; - parser->code_size += sizeof(njs_vmcode_2addr_t); parser->node = stmt; - left = stmt; + obj->ctor = 0; + if (token == NJS_TOKEN_CLOSE_BRACKET) { break; } diff -r cec366d97854 -r bf848210269c njs/njs_vm.c --- a/njs/njs_vm.c Sat Oct 22 20:24:32 2016 +0300 +++ b/njs/njs_vm.c Mon Oct 24 14:12:12 2016 +0300 @@ -366,7 +366,7 @@ njs_vmcode_object(njs_vm_t *vm, njs_valu njs_ret_t njs_vmcode_array(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) { - uint32_t size; + uint32_t length; njs_array_t *array; njs_value_t *value; njs_vmcode_array_t *code; @@ -376,14 +376,22 @@ njs_vmcode_array(njs_vm_t *vm, njs_value array = njs_array_alloc(vm, code->length, NJS_ARRAY_SPARE); if (nxt_fast_path(array != NULL)) { - size = array->size; - value = array->start; - - do { - njs_set_invalid(value); - value++; - size--; - } while (size != 0); + + if (code->code.ctor) { + /* Array of the form [,,,], [1,,]. */ + value = array->start; + length = array->length; + + do { + njs_set_invalid(value); + value++; + length--; + } while (length != 0); + + } else { + /* Array of the form [], [,,1], [1,2,3]. */ + array->length = 0; + } vm->retval.data.u.array = array; vm->retval.type = NJS_ARRAY; @@ -1039,7 +1047,9 @@ static njs_ret_t njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *object, int32_t index) { + size_t size; njs_ret_t ret; + njs_value_t *value; njs_array_t *array; array = object->data.u.array; @@ -1057,6 +1067,15 @@ njs_array_property_query(njs_vm_t *vm, n } } + value = &array->start[array->length]; + size = index - array->length; + + while (size != 0) { + njs_set_invalid(value); + value++; + size--; + } + array->length = index + 1; } @@ -1182,7 +1201,7 @@ njs_vmcode_property_foreach(njs_vm_t *vm next->lhe.proto = &njs_object_hash_proto; next->index = -1; - if (njs_is_array(object) && object->data.u.array->size != 0) { + if (njs_is_array(object) && object->data.u.array->length != 0) { next->index = 0; } @@ -1222,7 +1241,7 @@ njs_vmcode_property_next(njs_vm_t *vm, n if (next->index >= 0) { array = object->data.u.array; - while ((uint32_t) next->index < array->size) { + while ((uint32_t) next->index < array->length) { n = next->index++; if (njs_is_valid(&array->start[n])) { From igor at sysoev.ru Mon Oct 24 12:03:52 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 12:03:52 +0000 Subject: [njs] njs_array_realloc() has been changed to njs_array_expand(). Message-ID: details: http://hg.nginx.org/njs/rev/50555ae1d978 branches: changeset: 213:50555ae1d978 user: Igor Sysoev date: Mon Oct 24 14:56:28 2016 +0300 description: njs_array_realloc() has been changed to njs_array_expand(). diffstat: njs/njs_array.c | 58 +++++++++++++++++++++++++++---------------------------- njs/njs_array.h | 2 +- njs/njs_string.c | 8 ++---- njs/njs_vm.c | 17 ++++++--------- 4 files changed, 39 insertions(+), 46 deletions(-) diffs (178 lines): diff -r bf848210269c -r 50555ae1d978 njs/njs_array.c --- a/njs/njs_array.c Mon Oct 24 14:12:12 2016 +0300 +++ b/njs/njs_array.c Mon Oct 24 14:56:28 2016 +0300 @@ -148,17 +148,14 @@ njs_array_add(njs_vm_t *vm, njs_array_t { njs_ret_t ret; - if (array->size == array->length) { - ret = njs_array_realloc(vm, array, 0, array->size + 1); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } + ret = njs_array_expand(vm, array, 0, 1); + + if (nxt_fast_path(ret == NXT_OK)) { + /* GC: retain value. */ + array->start[array->length++] = *value; } - /* GC: retain value. */ - array->start[array->length++] = *value; - - return NXT_OK; + return ret; } @@ -168,31 +165,34 @@ njs_array_string_add(njs_vm_t *vm, njs_a { njs_ret_t ret; - if (array->size == array->length) { - ret = njs_array_realloc(vm, array, 0, array->size + 1); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } + ret = njs_array_expand(vm, array, 0, 1); + + if (nxt_fast_path(ret == NXT_OK)) { + return njs_string_create(vm, &array->start[array->length++], + start, size, length); } - return njs_string_create(vm, &array->start[array->length++], - start, size, length); + return ret; } njs_ret_t -njs_array_realloc(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, +njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, uint32_t size) { njs_value_t *start, *old; - if (size != array->size) { - if (size < 16) { - size *= 2; + size += array->length; - } else { - size += size / 2; - } + if (nxt_fast_path(size <= array->size && prepend == 0)) { + return NXT_OK; + } + + if (size < 16) { + size *= 2; + + } else { + size += size / 2; } start = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t), @@ -438,11 +438,9 @@ njs_array_prototype_push(njs_vm_t *vm, n array = args[0].data.u.array; if (nargs != 0) { - if (nargs > array->size - array->length) { - ret = njs_array_realloc(vm, array, 0, array->size + nargs); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } + ret = njs_array_expand(vm, array, 0, nargs); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; } for (i = 1; i < nargs; i++) { @@ -500,7 +498,7 @@ njs_array_prototype_unshift(njs_vm_t *vm if (n != 0) { if ((intptr_t) n > (array->start - array->data)) { - ret = njs_array_realloc(vm, array, n, 0); + ret = njs_array_expand(vm, array, n, 0); if (nxt_slow_path(ret != NXT_OK)) { return ret; } @@ -627,7 +625,7 @@ njs_array_prototype_splice(njs_vm_t *vm, * Index of the first item is in "n". */ if (delta > 0) { - ret = njs_array_realloc(vm, array, 0, array->size + delta); + ret = njs_array_expand(vm, array, 0, delta); if (nxt_slow_path(ret != NXT_OK)) { return ret; } diff -r bf848210269c -r 50555ae1d978 njs/njs_array.h --- a/njs/njs_array.h Mon Oct 24 14:12:12 2016 +0300 +++ b/njs/njs_array.h Mon Oct 24 14:56:28 2016 +0300 @@ -14,7 +14,7 @@ njs_array_t *njs_array_alloc(njs_vm_t *vm, uint32_t length, uint32_t spare); njs_ret_t njs_array_string_add(njs_vm_t *vm, njs_array_t *array, u_char *start, size_t size, size_t length); -njs_ret_t njs_array_realloc(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, +njs_ret_t njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend, uint32_t size); njs_ret_t njs_array_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); diff -r bf848210269c -r 50555ae1d978 njs/njs_string.c --- a/njs/njs_string.c Mon Oct 24 14:12:12 2016 +0300 +++ b/njs/njs_string.c Mon Oct 24 14:56:28 2016 +0300 @@ -1659,11 +1659,9 @@ njs_string_match_multiple(njs_vm_t *vm, string.size, vm->single_match_data); if (ret >= 0) { if (array != NULL) { - if (array->length == array->size) { - ret = njs_array_realloc(vm, array, 0, array->size + 1); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } + ret = njs_array_expand(vm, array, 0, 1); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; } } else { diff -r bf848210269c -r 50555ae1d978 njs/njs_vm.c --- a/njs/njs_vm.c Mon Oct 24 14:12:12 2016 +0300 +++ b/njs/njs_vm.c Mon Oct 24 14:56:28 2016 +0300 @@ -1047,28 +1047,25 @@ static njs_ret_t njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *object, int32_t index) { - size_t size; + int32_t size; njs_ret_t ret; njs_value_t *value; njs_array_t *array; array = object->data.u.array; - - if ((uint32_t) index >= array->length) { - + size = index - array->length; + + if (size >= 0) { if (pq->query != NJS_PROPERTY_QUERY_SET) { return NXT_DECLINED; } - if ((uint32_t) index >= array->size) { - ret = njs_array_realloc(vm, array, 0, index + 1); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } + ret = njs_array_expand(vm, array, 0, size + 1); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; } value = &array->start[array->length]; - size = index - array->length; while (size != 0) { njs_set_invalid(value); From igor at sysoev.ru Mon Oct 24 12:05:36 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 12:05:36 +0000 Subject: [njs] Version 0.1.4. Message-ID: details: http://hg.nginx.org/njs/rev/508689c1fb94 branches: changeset: 214:508689c1fb94 user: Igor Sysoev date: Mon Oct 24 15:04:50 2016 +0300 description: Version 0.1.4. diffstat: Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (10 lines): diff -r 50555ae1d978 -r 508689c1fb94 Makefile --- a/Makefile Mon Oct 24 14:56:28 2016 +0300 +++ b/Makefile Mon Oct 24 15:04:50 2016 +0300 @@ -1,5 +1,5 @@ -NJS_VER = 0.1.3 +NJS_VER = 0.1.4 NXT_LIB = nxt From igor at sysoev.ru Mon Oct 24 12:05:37 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 12:05:37 +0000 Subject: [njs] Added tag 0.1.4 for changeset 508689c1fb94 Message-ID: details: http://hg.nginx.org/njs/rev/4b187e72aa9d branches: changeset: 215:4b187e72aa9d user: Igor Sysoev date: Mon Oct 24 15:04:57 2016 +0300 description: Added tag 0.1.4 for changeset 508689c1fb94 diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 508689c1fb94 -r 4b187e72aa9d .hgtags --- a/.hgtags Mon Oct 24 15:04:50 2016 +0300 +++ b/.hgtags Mon Oct 24 15:04:57 2016 +0300 @@ -2,3 +2,4 @@ cdb8d20935ee96f1fa0c99d994d4b11cefcbc119 0039a747d25a3e08792c23c43b75768896724031 0.1.1 5b066b4db54c17dc0a9a72948474f36957462e87 0.1.2 360449773d51e7f451e5396e27021badc6b86085 0.1.3 +508689c1fb94c23f6b24be087c1dc63b2f9e6654 0.1.4 From igor at sysoev.ru Mon Oct 24 15:53:44 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 15:53:44 +0000 Subject: [njs] A build with -Werror=old-style-definition has been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/f87eefdd2c3d branches: changeset: 216:f87eefdd2c3d user: Igor Sysoev date: Mon Oct 24 17:16:10 2016 +0300 description: A build with -Werror=old-style-definition has been fixed. Patch by Piotr Sikora. diffstat: nxt/auto/clang | 10 +++++----- nxt/auto/getrandom | 2 +- nxt/auto/memalign | 4 ++-- nxt/auto/pcre | 2 +- nxt/auto/time | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diffs (114 lines): diff -r 4b187e72aa9d -r f87eefdd2c3d nxt/auto/clang --- a/nxt/auto/clang Mon Oct 24 15:04:57 2016 +0300 +++ b/nxt/auto/clang Mon Oct 24 17:16:10 2016 +0300 @@ -185,7 +185,7 @@ nxt_feature_name=NXT_HAVE_BUILTIN_UNREAC nxt_feature_run=no nxt_feature_incs= nxt_feature_libs= -nxt_feature_test="int main() { +nxt_feature_test="int main(void) { __builtin_unreachable(); }" . ${NXT_AUTO}feature @@ -196,7 +196,7 @@ nxt_feature_name=NXT_HAVE_BUILTIN_PREFET nxt_feature_run=no nxt_feature_incs= nxt_feature_libs= -nxt_feature_test="int main() { +nxt_feature_test="int main(void) { __builtin_prefetch(0); }" . ${NXT_AUTO}feature @@ -209,7 +209,7 @@ nxt_feature_path= nxt_feature_libs= nxt_feature_test="int n __attribute__ ((visibility(\"default\"))); - int main() { + int main(void) { return 1; }" . ${NXT_AUTO}feature @@ -228,7 +228,7 @@ nxt_feature_test="#include return malloc(1); } - int main() { + int main(void) { if (f() != NULL) { return 1; } @@ -255,7 +255,7 @@ else nxt_feature_libs= nxt_feature_test="int n __attribute__ ((aligned(64))); - int main() { + int main(void) { return 1; }" . ${NXT_AUTO}feature diff -r 4b187e72aa9d -r f87eefdd2c3d nxt/auto/getrandom --- a/nxt/auto/getrandom Mon Oct 24 15:04:57 2016 +0300 +++ b/nxt/auto/getrandom Mon Oct 24 17:16:10 2016 +0300 @@ -14,7 +14,7 @@ nxt_feature_test="#include #include #include - int main() { + int main(void) { char buf[4]; (void) syscall(SYS_getrandom, buf, 4, 0); diff -r 4b187e72aa9d -r f87eefdd2c3d nxt/auto/memalign --- a/nxt/auto/memalign Mon Oct 24 15:04:57 2016 +0300 +++ b/nxt/auto/memalign Mon Oct 24 17:16:10 2016 +0300 @@ -13,7 +13,7 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include - int main() { + int main(void) { void *p; if (posix_memalign(&p, 4096, 4096) != 0) @@ -34,7 +34,7 @@ if [ $nxt_found = no ]; then nxt_feature_libs= nxt_feature_test="#include - int main() { + int main(void) { if (memalign(4096, 4096) == NULL) return 1; return 0; diff -r 4b187e72aa9d -r f87eefdd2c3d nxt/auto/pcre --- a/nxt/auto/pcre Mon Oct 24 15:04:57 2016 +0300 +++ b/nxt/auto/pcre Mon Oct 24 17:16:10 2016 +0300 @@ -20,7 +20,7 @@ if /bin/sh -c "(pcre-config --version)" nxt_feature_libs=$NXT_PCRE_LIB nxt_feature_test="#include - int main() { + int main(void) { pcre *re; re = pcre_compile(NULL, 0, NULL, 0, NULL); diff -r 4b187e72aa9d -r f87eefdd2c3d nxt/auto/time --- a/nxt/auto/time Mon Oct 24 15:04:57 2016 +0300 +++ b/nxt/auto/time Mon Oct 24 17:16:10 2016 +0300 @@ -12,7 +12,7 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include - int main() { + int main(void) { time_t t; struct tm tm; @@ -32,7 +32,7 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include - int main() { + int main(void) { altzone = 0; return 0; }" From igor at sysoev.ru Mon Oct 24 15:53:46 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 15:53:46 +0000 Subject: [njs] A build with -Werror=return-type has been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/eef409d1d4be branches: changeset: 217:eef409d1d4be user: Igor Sysoev date: Mon Oct 24 17:23:00 2016 +0300 description: A build with -Werror=return-type has been fixed. Patch by Piotr Sikora. diffstat: nxt/auto/clang | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r f87eefdd2c3d -r eef409d1d4be nxt/auto/clang --- a/nxt/auto/clang Mon Oct 24 17:16:10 2016 +0300 +++ b/nxt/auto/clang Mon Oct 24 17:23:00 2016 +0300 @@ -198,6 +198,7 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="int main(void) { __builtin_prefetch(0); + return 0; }" . ${NXT_AUTO}feature From igor at sysoev.ru Mon Oct 24 15:53:47 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 15:53:47 +0000 Subject: [njs] Style unification of configure feature tests. Message-ID: details: http://hg.nginx.org/njs/rev/0fe25989e0a6 branches: changeset: 218:0fe25989e0a6 user: Igor Sysoev date: Mon Oct 24 17:29:27 2016 +0300 description: Style unification of configure feature tests. diffstat: nxt/auto/clang | 10 +++++----- nxt/auto/getrandom | 2 +- nxt/auto/time | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diffs (76 lines): diff -r eef409d1d4be -r 0fe25989e0a6 nxt/auto/clang --- a/nxt/auto/clang Mon Oct 24 17:23:00 2016 +0300 +++ b/nxt/auto/clang Mon Oct 24 17:29:27 2016 +0300 @@ -205,20 +205,20 @@ nxt_feature_test="int main(void) { nxt_feature="GCC __attribute__ visibility" nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_VISIBILITY -nxt_feature_run= +nxt_feature_run=no nxt_feature_path= nxt_feature_libs= nxt_feature_test="int n __attribute__ ((visibility(\"default\"))); int main(void) { - return 1; + return 0; }" . ${NXT_AUTO}feature nxt_feature="GCC __attribute__ malloc" nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_MALLOC -nxt_feature_run= +nxt_feature_run=no nxt_feature_path= nxt_feature_libs= nxt_feature_test="#include @@ -251,13 +251,13 @@ else nxt_feature="GCC __attribute__ aligned" nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_ALIGNED - nxt_feature_run= + nxt_feature_run=no nxt_feature_path= nxt_feature_libs= nxt_feature_test="int n __attribute__ ((aligned(64))); int main(void) { - return 1; + return 0; }" . ${NXT_AUTO}feature diff -r eef409d1d4be -r 0fe25989e0a6 nxt/auto/getrandom --- a/nxt/auto/getrandom Mon Oct 24 17:23:00 2016 +0300 +++ b/nxt/auto/getrandom Mon Oct 24 17:29:27 2016 +0300 @@ -7,7 +7,7 @@ nxt_feature="getrandom()" nxt_feature_name=NXT_HAVE_GETRANDOM -nxt_feature_run= +nxt_feature_run=no nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include diff -r eef409d1d4be -r 0fe25989e0a6 nxt/auto/time --- a/nxt/auto/time Mon Oct 24 17:23:00 2016 +0300 +++ b/nxt/auto/time Mon Oct 24 17:29:27 2016 +0300 @@ -7,7 +7,7 @@ nxt_feature="struct tm.tm_gmtoff" nxt_feature_name=NXT_HAVE_TM_GMTOFF -nxt_feature_run= +nxt_feature_run=no nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include @@ -27,7 +27,7 @@ nxt_feature_test="#include nxt_feature="altzone" nxt_feature_name=NXT_HAVE_ALTZONE -nxt_feature_run= +nxt_feature_run=no nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include From igor at sysoev.ru Mon Oct 24 15:53:48 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 24 Oct 2016 15:53:48 +0000 Subject: [njs] Incomplete non-recursive parser has been removed. Message-ID: details: http://hg.nginx.org/njs/rev/12a38e4e030b branches: changeset: 219:12a38e4e030b user: Igor Sysoev date: Mon Oct 24 18:27:31 2016 +0300 description: Incomplete non-recursive parser has been removed. diffstat: Makefile | 16 - njs/njs_nonrecursive_parser.c | 1553 ----------------------------------------- 2 files changed, 0 insertions(+), 1569 deletions(-) diffs (truncated from 1597 to 1000 lines): diff -r 0fe25989e0a6 -r 12a38e4e030b Makefile --- a/Makefile Mon Oct 24 17:29:27 2016 +0300 +++ b/Makefile Mon Oct 24 18:27:31 2016 +0300 @@ -31,7 +31,6 @@ main: $(NXT_BUILDDIR)/libnjs.a $(NXT_BUILDDIR)/njs_builtin.o \ $(NXT_BUILDDIR)/njs_lexer.o \ $(NXT_BUILDDIR)/njs_lexer_keyword.o \ - $(NXT_BUILDDIR)/njs_nonrecursive_parser.o \ $(NXT_BUILDDIR)/njs_parser.o \ $(NXT_BUILDDIR)/njs_parser_expression.o \ $(NXT_BUILDDIR)/njs_generator.o \ @@ -64,7 +63,6 @@ main: $(NXT_BUILDDIR)/libnjs.a $(NXT_BUILDDIR)/njs_builtin.o \ $(NXT_BUILDDIR)/njs_lexer.o \ $(NXT_BUILDDIR)/njs_lexer_keyword.o \ - $(NXT_BUILDDIR)/njs_nonrecursive_parser.o \ $(NXT_BUILDDIR)/njs_parser.o \ $(NXT_BUILDDIR)/njs_parser_expression.o \ $(NXT_BUILDDIR)/njs_generator.o \ @@ -329,20 +327,6 @@ dist: -I$(NXT_LIB) -Injs \ njs/njs_lexer_keyword.c -$(NXT_BUILDDIR)/njs_nonrecursive_parser.o: \ - $(NXT_BUILDDIR)/libnxt.a \ - njs/njscript.h \ - njs/njs_vm.h \ - njs/njs_number.h \ - njs/njs_object.h \ - njs/njs_parser.h \ - njs/njs_nonrecursive_parser.c \ - - $(NXT_CC) -c -o $(NXT_BUILDDIR)/njs_nonrecursive_parser.o \ - $(NXT_CFLAGS) \ - -I$(NXT_LIB) -Injs \ - njs/njs_nonrecursive_parser.c - $(NXT_BUILDDIR)/njs_parser.o: \ $(NXT_BUILDDIR)/libnxt.a \ njs/njscript.h \ diff -r 0fe25989e0a6 -r 12a38e4e030b njs/njs_nonrecursive_parser.c --- a/njs/njs_nonrecursive_parser.c Mon Oct 24 17:29:27 2016 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1553 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef nxt_int_t (*njs_parser_operation_t)(njs_vm_t *vm, - njs_parser_t *parser, njs_token_t token, const void *data); - -typedef nxt_int_t (*njs_parser_stack_operation_t)(njs_vm_t *vm, - njs_parser_t *parser, const void *data); - - -#define NJS_TOKEN_ANY NJS_TOKEN_ILLEGAL -#define NJS_PARSER_NODE ((void *) -1) -#define NJS_PARSER_VOID ((void *) -2) - - -typedef struct { - njs_token_t token; - njs_parser_operation_t operation; - const void *data; - const void *primed; -} njs_parser_terminal_t; - - -#define NJS_PARSER_IGNORE_LINE_END 0 -#define NJS_PARSER_TEST_LINE_END 1 - - -typedef struct { - uint8_t take_line_end; /* 1 bit */ - uint8_t count; -#if (NXT_SUNC) - /* - * SunC supports C99 flexible array members but does not allow - * static struct's initialization with arbitrary number of members. - */ - const njs_parser_terminal_t terminal[9]; -#else - const njs_parser_terminal_t terminal[]; -#endif -} njs_parser_switch_t; - - -njs_token_t njs_parser_token(njs_parser_t *parser); -static void *njs_parser_stack_pop(njs_parser_t *parser); -static nxt_int_t njs_parser_stack_push(njs_vm_t *vm, njs_parser_t *parser, - const void *data); - -static const void *const njs_parser_statement[]; -static const void *const njs_parser_expression0[]; - - -/* STUB */ -static nxt_int_t top = -1; -static void *stack[1024]; -/**/ - - -njs_parser_node_t * -njs_nonrecursive_parser(njs_vm_t *vm, njs_parser_t *parser) -{ - nxt_int_t ret; - njs_token_t token; - njs_parser_stack_operation_t operation; - - if (top < 0) { - njs_parser_stack_push(vm, parser, njs_parser_statement); - } - - token = njs_parser_token(parser); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - /* TODO: NJS_TOKEN_AGAIN */ - return NULL; - } - - do { - operation = (njs_parser_stack_operation_t) njs_parser_stack_pop(parser); - - if (operation == NULL) { - - if (parser->lexer->token == NJS_TOKEN_END) { - return parser->node; - } - - break; - } - - ret = operation(vm, parser, njs_parser_stack_pop(parser)); - - } while (ret == NXT_OK); - - nxt_thread_log_error(NXT_LOG_ERR, "unexpected token"); - - return NULL; -} - - -njs_token_t -njs_parser_token(njs_parser_t *parser) -{ - njs_token_t token; - - do { - token = njs_lexer_token(parser->lexer); - - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - return token; - } - - } while (nxt_slow_path(token == NJS_TOKEN_LINE_END)); - - return token; -} - - -static void * -njs_parser_stack_pop(njs_parser_t *parser) -{ - if (top < 0) { - return NULL; - } - - return stack[top--]; -} - - -static nxt_int_t -njs_parser_stack_push(njs_vm_t *vm, njs_parser_t *parser, const void *data) -{ - void *const *next; - - next = data; - - if (next != NULL) { - - do { - top++; - - if (*next != NJS_PARSER_NODE) { - stack[top] = *next; - - } else { - stack[top] = parser->node; - } - - next++; - - } while (*next != NULL); - } - - return NXT_OK; -} - - -static nxt_int_t -njs_parser_switch(njs_vm_t *vm, njs_parser_t *parser, void *data) -{ - nxt_int_t ret; - nxt_uint_t n; - njs_token_t token; - njs_parser_switch_t *swtch; - const njs_parser_terminal_t *term; - - swtch = data; - token = parser->lexer->token; - - n = swtch->count; - term = swtch->terminal; - - do { - if (token == term->token || term->token == NJS_TOKEN_ANY) { - ret = term->operation(vm, parser, token, term->data); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; - } - - ret = njs_parser_stack_push(vm, parser, term->primed); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; - } - - if (term->token != NJS_TOKEN_ANY) { - token = njs_parser_token(parser); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - /* TODO: NJS_TOKEN_AGAIN */ - return NXT_ERROR; - } - } - - return NXT_OK; - } - - term++; - n--; - - } while (n != 0); - - return NXT_OK; -} - - -static nxt_int_t -njs_parser_statement_semicolon(njs_vm_t *vm, njs_parser_t *parser, - void *data) -{ - njs_token_t token; - njs_parser_node_t *node; - - node = data; - - switch (parser->lexer->token) { - - case NJS_TOKEN_SEMICOLON: - token = njs_parser_token(parser); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - /* TODO: NJS_TOKEN_AGAIN */ - return NXT_ERROR; - } - - /* Fall through. */ - - case NJS_TOKEN_END: - - node->right = parser->node; - parser->node = node; - - return NXT_OK; - - default: - break; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_test_token(njs_vm_t *vm, njs_parser_t *parser, void *data) -{ - njs_token_t token; - - token = (njs_token_t) data; - - if (parser->lexer->token == token) { - token = njs_parser_token(parser); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - /* TODO: NJS_TOKEN_AGAIN */ - return NXT_ERROR; - } - - return NXT_OK; - } - - vm->exception = &njs_exception_syntax_error; - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_node(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token, - const void *data) -{ - njs_parser_node_t *node; - - token = (njs_token_t) data; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->left = parser->node; - parser->node = node; - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_noop(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token, - const void *data) -{ - return NXT_OK; -} - - -static nxt_int_t -njs_parser_link_left(njs_vm_t *vm, njs_parser_t *parser, const void *data) -{ - njs_parser_node_t *node; - - node = (njs_parser_node_t *) data; - - node->left = parser->node; - parser->node = node; - - return NXT_OK; -} - - -static nxt_int_t -njs_parser_link_right(njs_vm_t *vm, njs_parser_t *parser, const void *data) -{ - njs_parser_node_t *node; - - node = (njs_parser_node_t *) data; - - node->right = parser->node; - parser->node = node; - - return NXT_OK; -} - - -static nxt_int_t -njs_parser_condition_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->left = parser->node; - parser->node = node; - parser->code_size += sizeof(njs_vmcode_cond_jump_t) - + sizeof(njs_vmcode_move_t) - + sizeof(njs_vmcode_jump_t) - + sizeof(njs_vmcode_move_t); - parser->branch = 1; - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_binary_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - njs_vmcode_operation_t operation; - - operation = (njs_vmcode_operation_t) data; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->u.operation = operation; - node->left = parser->node; - parser->node = node; - parser->code_size += sizeof(njs_vmcode_3addr_t); - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_post_unary_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - njs_vmcode_operation_t operation; - - operation = (njs_vmcode_operation_t) data; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->u.operation = operation; - node->left = parser->node; - parser->node = node; - parser->code_size += sizeof(njs_vmcode_3addr_t); - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_unary_expression0(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - njs_vmcode_operation_t operation; - - operation = (njs_vmcode_operation_t) data; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->u.operation = operation; - parser->node = node; - parser->code_size += sizeof(njs_vmcode_3addr_t); - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_unary_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - njs_vmcode_operation_t operation; - - operation = (njs_vmcode_operation_t) data; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->u.operation = operation; - parser->node = node; - parser->code_size += sizeof(njs_vmcode_2addr_t); - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_unary_plus_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - return njs_parser_unary_expression(vm, parser, - NJS_TOKEN_UNARY_PLUS, data); -} - - -static nxt_int_t -njs_parser_unary_plus_link(njs_vm_t *vm, njs_parser_t *parser, - const void *data) -{ - njs_parser_node_t *node; - - node = (njs_parser_node_t *) data; - - /* Skip the unary plus of number. */ - - if (parser->node->token != NJS_TOKEN_NUMBER) { - node->left = parser->node; - parser->node = node; - } - - return NXT_OK; -} - - -static nxt_int_t -njs_parser_unary_negation_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - return njs_parser_unary_expression(vm, parser, - NJS_TOKEN_UNARY_NEGATION, data); -} - - -static nxt_int_t -njs_parser_unary_negative_link(njs_vm_t *vm, njs_parser_t *parser, - void *data) -{ - double num; - njs_parser_node_t *node; - - node = data; - - if (parser->node->token == NJS_TOKEN_NUMBER) { - /* Optimization of common negative number. */ - node = parser->node; - num = -node->u.value.data.u.number; - node->u.value.data.u.number = num; - node->u.value.data.truth = njs_is_number_true(num); - - } else { - node->left = parser->node; - parser->node = node; - } - - return NXT_OK; -} - - -static nxt_int_t -njs_parser_name_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - nxt_uint_t level; - njs_extern_t *ext; - njs_variable_t *var; - njs_parser_node_t *node; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - ext = njs_parser_external(vm, parser); - - if (ext != NULL) { - node->token = NJS_TOKEN_EXTERNAL; - node->u.value.type = NJS_EXTERNAL; - node->u.value.data.truth = 1; - node->index = (njs_index_t) ext; - - } else { - node->token = token; - - var = njs_parser_variable(vm, parser, &level); - if (nxt_slow_path(var == NULL)) { - return NJS_TOKEN_ERROR; - } - - switch (var->state) { - - case NJS_VARIABLE_CREATED: - var->state = NJS_VARIABLE_PENDING; - parser->code_size += sizeof(njs_vmcode_1addr_t); - break; - - case NJS_VARIABLE_PENDING: - var->state = NJS_VARIABLE_USED; - parser->code_size += sizeof(njs_vmcode_1addr_t); - break; - - case NJS_VARIABLE_USED: - parser->code_size += sizeof(njs_vmcode_1addr_t); - break; - - case NJS_VARIABLE_SET: - case NJS_VARIABLE_DECLARED: - break; - } - - node->u.variable = var; - } - } - - parser->node = node; - - return NXT_OK; -} - - -static nxt_int_t -njs_parser_var_name(njs_vm_t *vm, njs_parser_t *parser, void *data) -{ - /* TODO disable NJS_TOKEN_EXTERNAL */ - return njs_parser_name_expression(vm, parser, NJS_TOKEN_NAME, data); -} - - -static nxt_int_t -njs_parser_this_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->index = NJS_INDEX_THIS; - parser->node = node; - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_string_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - nxt_int_t ret; - njs_parser_node_t *node; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - - ret = njs_parser_string_create(vm, &node->u.value); - if (nxt_slow_path(ret != NXT_OK)) { - return NJS_TOKEN_ERROR; - } - - parser->node = node; - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_number_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - double num; - njs_parser_node_t *node; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - num = parser->lexer->number; - node->u.value.data.u.number = num; - node->u.value.type = NJS_NUMBER; - node->u.value.data.truth = njs_is_number_true(num); - parser->node = node; - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_boolean_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->u.value = (parser->lexer->number == 0.0) ? njs_value_false: - njs_value_true; - parser->node = node; - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_undefined_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->u.value = njs_value_void; - parser->node = node; - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_null_expression(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - njs_parser_node_t *node; - - node = njs_parser_node_alloc(vm); - - if (nxt_fast_path(node != NULL)) { - node->token = token; - node->u.value = njs_value_null; - parser->node = node; - - return NXT_OK; - } - - return NXT_ERROR; -} - - -static nxt_int_t -njs_parser_syntax_error(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token, const void *data) -{ - vm->exception = &njs_exception_syntax_error; - - return NXT_ERROR; -} - - -/* - * The variables and literal values. - * - * VALUE = "(" EXPRESSION ")" - * [ NAME create_node ] - * [ "this" create_node ] - * [ STRING create_node ] - * [ NUMBER create_node ] - * [ BOOLEAN create_node ] - * [ "undefined" create_node ] - * [ "null" create_node ] - * ERROR - */ - -static const void *const njs_parser_grouping_expression[] = { - (void *) NJS_TOKEN_CLOSE_PARENTHESIS, (void *) njs_parser_test_token, - &njs_parser_expression0, (void *) njs_parser_stack_push, - NULL, -}; - - -static const njs_parser_switch_t njs_parser_value_expression_switch = { - NJS_PARSER_IGNORE_LINE_END, - 9, { - { NJS_TOKEN_OPEN_PARENTHESIS, njs_parser_noop, NULL, - &njs_parser_grouping_expression }, - - { NJS_TOKEN_NAME, njs_parser_name_expression, NULL, NULL }, - { NJS_TOKEN_THIS, njs_parser_this_expression, NULL, NULL }, - { NJS_TOKEN_STRING, njs_parser_string_expression, NULL, NULL }, - { NJS_TOKEN_NUMBER, njs_parser_number_expression, NULL, NULL }, - { NJS_TOKEN_BOOLEAN, njs_parser_boolean_expression, NULL, NULL }, - - { NJS_TOKEN_UNDEFINED, - njs_parser_undefined_expression, NULL, NULL }, - { NJS_TOKEN_NULL, njs_parser_null_expression, NULL, NULL }, - - { NJS_TOKEN_ANY, njs_parser_syntax_error, NULL, NULL }, - } -}; - - -#if 0 - -static const void *const njs_parser_value_expression[] = { - &njs_parser_value_expression_switch, (void *) njs_parser_switch, - NULL, -}; - -#endif - - -/* - * The postfix increment and decrement operations. - * - * POSTFIX_INC_DEC = VALUE [ "++" create_node ] - * VALUE [ "--" create_node ] - * <> - */ - - -static const njs_parser_switch_t njs_parser_post_inc_dec_expression_switch = { - NJS_PARSER_IGNORE_LINE_END, - 2, { - { NJS_TOKEN_INCREMENT, - njs_parser_post_unary_expression, - (void *) njs_vmcode_post_increment, NULL }, - - { NJS_TOKEN_DECREMENT, - njs_parser_post_unary_expression, - (void *) njs_vmcode_post_decrement, NULL }, - } -}; - - -static const void *const njs_parser_post_inc_dec_expression[] = { - &njs_parser_post_inc_dec_expression_switch, (void *) njs_parser_switch, - &njs_parser_value_expression_switch, (void *) njs_parser_switch, - NULL, -}; - - -/* - * The prefix increment and decrement operations. - * - * PREFIX_INC_DEC = [ "++" create_node ] POSTFIX_INC_DEC link_left - * [ "--" create_node ] POSTFIX_INC_DEC link_left - * <> POSTFIX_INC_DEC - */ - -static const void *const njs_parser_inc_dec_expression_primed[] = { - NJS_PARSER_NODE, (void *) njs_parser_link_left, - &njs_parser_value_expression_switch, (void *) njs_parser_switch, - NULL, -}; - - -static const njs_parser_switch_t njs_parser_inc_dec_expression_switch = { - NJS_PARSER_IGNORE_LINE_END, - 3, { - { NJS_TOKEN_INCREMENT, - njs_parser_unary_expression0, (void *) njs_vmcode_increment, - njs_parser_inc_dec_expression_primed }, - - { NJS_TOKEN_DECREMENT, - njs_parser_unary_expression0, (void *) njs_vmcode_decrement, - njs_parser_inc_dec_expression_primed }, - - { NJS_TOKEN_ANY, njs_parser_noop, NULL, - njs_parser_post_inc_dec_expression }, - } -}; - - -static const void *const njs_parser_inc_dec_expression[] = { - &njs_parser_inc_dec_expression_switch, (void *) njs_parser_switch, - NULL, -}; - - -/* - * The unary operations. - * - * UNARY = [ "+" create_node ] UNARY plus_link_left - * [ "-" create_node ] UNARY negation_link_left - * [ "!" create_node ] UNARY link_left - * [ "~" create_node ] UNARY link_left - * [ "typeof" create_node ] UNARY link_left - * [ "void" create_node ] UNARY link_left - * [ "delete" create_node ] UNARY link_left - * <> INC_DEC - */ - -static const njs_parser_switch_t njs_parser_unary_expression_switch; - -static const void *const njs_parser_unary_plus_expression_primed[] = { - NJS_PARSER_NODE, (void *) njs_parser_unary_plus_link, - &njs_parser_unary_expression_switch, (void *) njs_parser_switch, - NULL, -}; - - -static const void *const njs_parser_unary_negative_expression_primed[] = { - NJS_PARSER_NODE, (void *) njs_parser_unary_negative_link, - &njs_parser_unary_expression_switch, (void *) njs_parser_switch, - NULL, -}; - - -static const void *const njs_parser_unary_expression_primed[] = { - NJS_PARSER_NODE, (void *) njs_parser_link_left, - &njs_parser_unary_expression_switch, (void *) njs_parser_switch, - NULL, -}; - - -static const njs_parser_switch_t njs_parser_unary_expression_switch = { - NJS_PARSER_TEST_LINE_END, - 8, { - { NJS_TOKEN_ADDITION, - njs_parser_unary_plus_expression, (void *) njs_vmcode_unary_plus, - njs_parser_unary_plus_expression_primed }, - - { NJS_TOKEN_SUBSTRACTION, - njs_parser_unary_negation_expression, - (void *) njs_vmcode_unary_negation, - njs_parser_unary_negative_expression_primed }, - - { NJS_TOKEN_LOGICAL_NOT, - njs_parser_unary_expression, (void *) njs_vmcode_logical_not, - njs_parser_unary_expression_primed }, - - { NJS_TOKEN_BITWISE_NOT, - njs_parser_unary_expression, (void *) njs_vmcode_bitwise_not, - njs_parser_unary_expression_primed }, - - { NJS_TOKEN_TYPEOF, - njs_parser_unary_expression, (void *) njs_vmcode_typeof, - njs_parser_unary_expression_primed }, - - { NJS_TOKEN_VOID, - njs_parser_unary_expression, (void *) njs_vmcode_void, - njs_parser_unary_expression_primed }, - - { NJS_TOKEN_DELETE, - njs_parser_unary_expression, (void *) njs_vmcode_delete, - njs_parser_unary_expression_primed }, - - { NJS_TOKEN_ANY, njs_parser_noop, NULL, - njs_parser_inc_dec_expression }, - } -}; - - -/* - * The left associative multiplication, division and remainder operations. - * - * MULTIPLICATION = UNARY MULTIPLICATION' - * MULTIPLICATION' = [ "*" create_node ] UNARY link_right MULTIPLICATION' - * [ "/" create_node ] UNARY link_right MULTIPLICATION' - * [ "%" create_node ] UNARY link_right MULTIPLICATION' - * <> - */ - -static const njs_parser_switch_t njs_parser_multiplicative_expression_switch; - -static const void *const njs_parser_multiplicative_expression_primed[] = { - &njs_parser_multiplicative_expression_switch, (void *) njs_parser_switch, - NJS_PARSER_NODE, (void *) njs_parser_link_right, - &njs_parser_unary_expression_switch, (void *) njs_parser_switch, - NULL, -}; - - -static const njs_parser_switch_t - njs_parser_multiplicative_expression_switch = -{ - NJS_PARSER_TEST_LINE_END, - 3, { - { NJS_TOKEN_MULTIPLICATION, - njs_parser_binary_expression, (void *) njs_vmcode_multiplication, - njs_parser_multiplicative_expression_primed }, - - { NJS_TOKEN_DIVISION, - njs_parser_binary_expression, (void *) njs_vmcode_division, From zelenkov at nginx.com Tue Oct 25 14:33:39 2016 From: zelenkov at nginx.com (Andrey Zelenkov) Date: Tue, 25 Oct 2016 14:33:39 +0000 Subject: [njs] Array.prototype.lastIndexOf() and Array.prototype.indexOf(... Message-ID: details: http://hg.nginx.org/njs/rev/76e57071e411 branches: changeset: 220:76e57071e411 user: Andrey Zelenkov date: Mon Oct 24 19:02:31 2016 +0300 description: Array.prototype.lastIndexOf() and Array.prototype.indexOf() fixes. The fromIndex parameter processing in lastIndexOf() has been fixed. The lastIndexOf() search algorithm has been optimized. The njs_array_index_of() function has been removed. In collaboration with Valentin Bartenev. diffstat: njs/njs_array.c | 125 +++++++++++++++++++++++++++++++++------------- njs/test/njs_unit_test.c | 25 ++++++++- 2 files changed, 112 insertions(+), 38 deletions(-) diffs (215 lines): diff -r 12a38e4e030b -r 76e57071e411 njs/njs_array.c --- a/njs/njs_array.c Mon Oct 24 18:27:31 2016 +0300 +++ b/njs/njs_array.c Mon Oct 24 19:02:31 2016 +0300 @@ -84,8 +84,6 @@ static njs_ret_t njs_array_prototype_to_ static njs_ret_t njs_array_prototype_join_continuation(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static njs_value_t *njs_array_copy(njs_value_t *dst, njs_value_t *src); -static njs_ret_t njs_array_index_of(njs_vm_t *vm, njs_value_t *args, - nxt_uint_t nargs, nxt_bool_t first); static njs_ret_t njs_array_prototype_for_each_continuation(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); static njs_ret_t njs_array_prototype_some_continuation(njs_vm_t *vm, @@ -974,7 +972,59 @@ static njs_ret_t njs_array_prototype_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - return njs_array_index_of(vm, args, nargs, 1); + nxt_int_t i, index, length; + njs_value_t *value, *start; + njs_array_t *array; + + index = -1; + + if (nargs < 2 || !njs_is_array(&args[0])) { + goto done; + } + + array = args[0].data.u.array; + length = array->length; + + if (length == 0) { + goto done; + } + + i = 0; + + if (nargs > 2) { + i = args[2].data.u.number; + + if (i >= length) { + goto done; + } + + if (i < 0) { + i += length; + + if (i < 0) { + i = 0; + } + } + } + + value = &args[1]; + start = array->start; + + do { + if (njs_values_strict_equal(value, &start[i])) { + index = i; + break; + } + + i++; + + } while (i < length); + +done: + + njs_number_set(&vm->retval, index); + + return NXT_OK; } @@ -982,51 +1032,54 @@ static njs_ret_t njs_array_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - return njs_array_index_of(vm, args, nargs, 0); -} - - -static njs_ret_t -njs_array_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, - nxt_bool_t first) -{ - nxt_int_t i, index, length; - njs_value_t *value; + nxt_int_t i, n, index, length; + njs_value_t *value, *start; njs_array_t *array; index = -1; - if (nargs > 1 && njs_is_array(&args[0])) { - i = 0; - array = args[0].data.u.array; - length = array->length; + if (nargs < 2 || !njs_is_array(&args[0])) { + goto done; + } - if (nargs > 2) { - i = args[2].data.u.number; + array = args[0].data.u.array; + length = array->length; + + if (length == 0) { + goto done; + } + + i = length - 1; + + if (nargs > 2) { + n = args[2].data.u.number; + + if (n < 0) { + i = n + length; if (i < 0) { - i += length; + goto done; + } - if (i < 0) { - i = 0; - } - } + } else if (n < length) { + i = n; + } + } + + value = &args[1]; + start = array->start; + + do { + if (njs_values_strict_equal(value, &start[i])) { + index = i; + break; } - value = &args[1]; - - while (i < length) { - if (njs_values_strict_equal(value, &array->start[i])) { - index = i; + i--; - if (first) { - break; - } - } + } while (i >= 0); - i++; - } - } +done: njs_number_set(&vm->retval, index); diff -r 12a38e4e030b -r 76e57071e411 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 24 18:27:31 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Oct 24 19:02:31 2016 +0300 @@ -2362,6 +2362,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [1,2,3,4]; a.indexOf(5)"), nxt_string("-1") }, + { nxt_string("var a = [1,2,3,4]; a.indexOf(4, 3)"), + nxt_string("3") }, + + { nxt_string("var a = [1,2,3,4]; a.indexOf(4, 4)"), + nxt_string("-1") }, + { nxt_string("var a = [1,2,3,4,3,4]; a.indexOf(3, '2')"), nxt_string("2") }, @@ -2374,20 +2380,35 @@ static njs_unit_test_t njs_test[] = { nxt_string("[].indexOf.bind(0)(0, 0)"), nxt_string("-1") }, + { nxt_string("[].lastIndexOf(1, -1)"), + nxt_string("-1") }, + { nxt_string("var a = [1,2,3,4]; a.lastIndexOf()"), nxt_string("-1") }, { nxt_string("var a = [1,2,3,4]; a.lastIndexOf(5)"), nxt_string("-1") }, + { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(1, 0)"), + nxt_string("0") }, + { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(3, '2')"), - nxt_string("4") }, + nxt_string("2") }, + + { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(1, 6)"), + nxt_string("0") }, + + { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(2, 6)"), + nxt_string("1") }, { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(4, -1)"), nxt_string("5") }, + { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(4, -6)"), + nxt_string("-1") }, + { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(3, -10)"), - nxt_string("4") }, + nxt_string("-1") }, { nxt_string("var a = []; var s = { sum: 0 };" "a.forEach(function(v, i, a) { this.sum += v }, s); s.sum"), From igor at sysoev.ru Tue Oct 25 15:44:10 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 25 Oct 2016 15:44:10 +0000 Subject: [njs] Array.prototypes.includes() method. Message-ID: details: http://hg.nginx.org/njs/rev/f21747d5ac83 branches: changeset: 221:f21747d5ac83 user: Igor Sysoev date: Tue Oct 25 17:52:18 2016 +0300 description: Array.prototypes.includes() method. diffstat: njs/njs_array.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 30 ++++++++++++++++ 2 files changed, 115 insertions(+), 0 deletions(-) diffs (142 lines): diff -r 76e57071e411 -r f21747d5ac83 njs/njs_array.c --- a/njs/njs_array.c Mon Oct 24 19:02:31 2016 +0300 +++ b/njs/njs_array.c Tue Oct 25 17:52:18 2016 +0300 @@ -1088,6 +1088,83 @@ done: static njs_ret_t +njs_array_prototype_includes(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + nxt_int_t i, length; + njs_value_t *value, *start; + njs_array_t *array; + const njs_value_t *retval; + + retval = &njs_value_false; + + if (nargs < 2 || !njs_is_array(&args[0])) { + goto done; + } + + array = args[0].data.u.array; + length = array->length; + + if (length == 0) { + goto done; + } + + i = 0; + + if (nargs > 2) { + i = args[2].data.u.number; + + if (i >= length) { + goto done; + } + + if (i < 0) { + i += length; + + if (i < 0) { + i = 0; + } + } + } + + start = array->start; + value = &args[1]; + + if (njs_is_number(value) && njs_is_nan(value->data.u.number)) { + + do { + value = &start[i]; + + if (njs_is_number(value) && njs_is_nan(value->data.u.number)) { + retval = &njs_value_true; + break; + } + + i++; + + } while (i < length); + + } else { + do { + if (njs_values_strict_equal(value, &start[i])) { + retval = &njs_value_true; + break; + } + + i++; + + } while (i < length); + } + +done: + + vm->retval = *retval; + + return NXT_OK; +} + + +static njs_ret_t njs_array_prototype_for_each(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -1804,6 +1881,14 @@ static const njs_object_prop_t njs_arra NJS_OBJECT_ARG, NJS_SKIP_ARG, NJS_INTEGER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("includes"), + .value = njs_native_function(njs_array_prototype_includes, 0, + NJS_OBJECT_ARG, NJS_SKIP_ARG, NJS_INTEGER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("forEach"), diff -r 76e57071e411 -r f21747d5ac83 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 24 19:02:31 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Oct 25 17:52:18 2016 +0300 @@ -2410,6 +2410,36 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [1,2,3,4,3,4]; a.lastIndexOf(3, -10)"), nxt_string("-1") }, + { nxt_string("[1,2,3,4].includes()"), + nxt_string("false") }, + + { nxt_string("[1,2,3,4].includes(5)"), + nxt_string("false") }, + + { nxt_string("[1,2,3,4].includes(4, 3)"), + nxt_string("true") }, + + { nxt_string("[1,2,3,4].includes(4, 4)"), + nxt_string("false") }, + + { nxt_string("[1,2,3,4,3,4].includes(3, '2')"), + nxt_string("true") }, + + { nxt_string("[1,2,3,4,3,4].includes(4, -1)"), + nxt_string("true") }, + + { nxt_string("[1,2,3,4,3,4].includes(3, -10)"), + nxt_string("true") }, + + { nxt_string("[1,2,3,NaN,3,4].includes(NaN)"), + nxt_string("true") }, + + { nxt_string("[1,2,3,4,5].includes(NaN)"), + nxt_string("false") }, + + { nxt_string("[].includes.bind(0)(0, 0)"), + nxt_string("false") }, + { nxt_string("var a = []; var s = { sum: 0 };" "a.forEach(function(v, i, a) { this.sum += v }, s); s.sum"), nxt_string("0") }, From mdounin at mdounin.ru Tue Oct 25 19:34:58 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 25 Oct 2016 22:34:58 +0300 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. In-Reply-To: References: Message-ID: <20161025193458.GA73038@mdounin.ru> Hello! On Wed, Oct 19, 2016 at 02:43:24PM +0800, ?? (hucc) wrote: > Hello! > > > Thanks for reminding me! Illegal character should be checked > also error detection in configration parser is needed. > > > Considering that ngx_atofp() was used in some 3rd party modules, > Would nginx-devel accept a new function like ngx_ato??() or > lround(strtod()), or just let strtod() alone? Using strtod() should be avoided as it has other problems, see https://trac.nginx.org/nginx/ticket/475. That is, an additional variant of ngx_atofp() is a way to go. Last time we've looked into this, we've stumbled upon selecting a proper name for the additional function. Looking into this again I tend to think that proper solution would be to use a special function withing the ngx_http_mp4_module itself. Patch below. # HG changeset patch # User Maxim Dounin # Date 1477416871 -10800 # Tue Oct 25 20:34:31 2016 +0300 # Node ID 16dae7d3b770c63dc16ac06312a66c1bafc3308f # Parent 56d6bfe6b609c565a9f500bde573fd9b488ff960 Mp4: introduced custom version of ngx_atofp(). This allows to correctly parse "start" and "end" arguments without null-termination (ticket #475), and also fixes rounding errors observed with strtod() when using i387 instructions. diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c +++ b/src/http/modules/ngx_http_mp4_module.c @@ -216,6 +216,7 @@ typedef struct { static ngx_int_t ngx_http_mp4_handler(ngx_http_request_t *r); +static ngx_int_t ngx_http_mp4_atofp(u_char *line, size_t n, size_t point); static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4); static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4, @@ -537,26 +538,15 @@ ngx_http_mp4_handler(ngx_http_request_t /* * A Flash player may send start value with a lot of digits - * after dot so strtod() is used instead of atofp(). NaNs and - * infinities become negative numbers after (int) conversion. + * after dot so a custom function is used instead of ngx_atofp(). */ - ngx_set_errno(0); - start = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - start = -1; - } + start = ngx_http_mp4_atofp(value.data, value.len, 3); } if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) { - ngx_set_errno(0); - end = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - end = -1; - } + end = ngx_http_mp4_atofp(value.data, value.len, 3); if (end > 0) { if (start < 0) { @@ -687,6 +677,62 @@ ngx_http_mp4_handler(ngx_http_request_t static ngx_int_t +ngx_http_mp4_atofp(u_char *line, size_t n, size_t point) +{ + ngx_int_t value, cutoff, cutlim; + ngx_uint_t dot; + + /* same as ngx_atofp(), but allows additional digits */ + + if (n == 0) { + return NGX_ERROR; + } + + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; + + dot = 0; + + for (value = 0; n--; line++) { + + if (point == 0) { + break; + } + + if (*line == '.') { + if (dot) { + return NGX_ERROR; + } + + dot = 1; + continue; + } + + if (*line < '0' || *line > '9') { + return NGX_ERROR; + } + + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + + value = value * 10 + (*line - '0'); + point -= dot; + } + + while (point--) { + if (value > cutoff) { + return NGX_ERROR; + } + + value = value * 10; + } + + return value; +} + + +static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4) { off_t start_offset, end_offset, adjustment; -- Maxim Dounin http://nginx.org/ From hucong.c at foxmail.com Wed Oct 26 09:10:25 2016 From: hucong.c at foxmail.com (=?gb18030?B?uvq0zyAoaHVjYyk=?=) Date: Wed, 26 Oct 2016 17:10:25 +0800 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. Message-ID: Hello! On Wed, Oct 26, 2016 3:34 AM, Maxim Dounin wrote: >Using strtod() should be avoided as it has other problems, see >https://trac.nginx.org/nginx/ticket/475. That is, an additional >variant of ngx_atofp() is a way to go. > > >Last time we've looked into this, we've stumbled upon selecting a >proper name for the additional function. Looking into this again >I tend to think that proper solution would be to use a special >function withing the ngx_http_mp4_module itself. Patch below. VOD (video on demand) module which support requesting time range also need the special function, so i would like to see that nginx-devel add a function in Core, that would be helpful. Possible patch below. # HG changeset patch # User hucongcong # Date 1477468236 -28800 # Wed Oct 26 15:50:36 2016 +0800 # Node ID 6376b8da3689011dfc8805381970f9ea2251c0a6 # Parent 56d6bfe6b609c565a9f500bde573fd9b488ff960 Core: add ngx_atosp(). This allows to correctly parse "start" and "end" arguments without null-termination (ticket #475), and also fixes rounding errors observed with strtod() when using i387 instructions. diff -r 56d6bfe6b609 -r 6376b8da3689 src/core/ngx_string.c --- a/src/core/ngx_string.c Fri Oct 21 16:28:39 2016 +0300 +++ b/src/core/ngx_string.c Wed Oct 26 15:50:36 2016 +0800 @@ -926,7 +926,9 @@ } -/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */ +/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050. + * can be replaced by ngx_atosp(line, n, point, 1). + */ ngx_int_t ngx_atofp(u_char *line, size_t n, size_t point) @@ -982,6 +984,76 @@ } +/* parse a fixed point number and do bounds check when strict is true, e.g., + * ngx_atosp("12.2193", 3, 0, 0) returns 12, + * ngx_atosp("12.2193", 3, 0, 1) returns NGX_ERROR, + * ngx_atosp("12.2193", 6, 3, 1) returns 12219, + * ngx_atosp("12.2193", 7, 3, 1) returns NGX_ERROR, + * ngx_atosp("12.2193", 7, 3, 0) returns 12219. + */ + +ngx_int_t +ngx_atosp(u_char *line, size_t n, size_t point, unsigned strict) +{ + ngx_int_t value, cutoff, cutlim; + ngx_uint_t dot; + + if (n == 0) { + return NGX_ERROR; + } + + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; + + dot = 0; + + for (value = 0; n--; line++) { + + if (*line == '.') { + if (dot) { + return NGX_ERROR; + } + + if (strict && point == 0) { + return NGX_ERROR; + } + + dot = 1; + continue; + } + + if (*line < '0' || *line > '9') { + return NGX_ERROR; + } + + if (dot && point == 0) { + if (strict) { + return NGX_ERROR; + } + + continue; + } + + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + + value = value * 10 + (*line - '0'); + point -= dot; + } + + while (point--) { + if (value > cutoff) { + return NGX_ERROR; + } + + value = value * 10; + } + + return value; +} + + ssize_t ngx_atosz(u_char *line, size_t n) { diff -r 56d6bfe6b609 -r 6376b8da3689 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Fri Oct 21 16:28:39 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Wed Oct 26 15:50:36 2016 +0800 @@ -537,26 +537,15 @@ /* * A Flash player may send start value with a lot of digits - * after dot so strtod() is used instead of atofp(). NaNs and - * infinities become negative numbers after (int) conversion. + * after dot so ngx_atosp() is used instead of ngx_atofp(). */ - ngx_set_errno(0); - start = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - start = -1; - } + start = ngx_atosp(value.data, value.len, 3, 0); } if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) { - ngx_set_errno(0); - end = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - end = -1; - } + end = ngx_atosp(value.data, value.len, 3, 0); if (end > 0) { if (start < 0) { -------------- next part -------------- An HTML attachment was scrubbed... URL: From hucong.c at foxmail.com Wed Oct 26 09:47:06 2016 From: hucong.c at foxmail.com (=?gb18030?B?uvq0zyAoaHVjYyk=?=) Date: Wed, 26 Oct 2016 17:47:06 +0800 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. Message-ID: Hello! On Wed, Oct 26, 2016 3:34 AM, Maxim Dounin wrote: >Using strtod() should be avoided as it has other problems, see >https://trac.nginx.org/nginx/ticket/475. That is, an additional >variant of ngx_atofp() is a way to go. > > >Last time we've looked into this, we've stumbled upon selecting a >proper name for the additional function. Looking into this again >I tend to think that proper solution would be to use a special >function withing the ngx_http_mp4_module itself. Patch below. Sorry, my mistake, last patch lost some codes when i transfer codes from Git to Mercurial. VOD (video on demand) module which support requesting time range also need the special function, so i would like to see that nginx-devel add a function in Core, that would be helpful. Possible patch below. # HG changeset patch # User hucongcong # Date 1477473854 -28800 # Wed Oct 26 17:24:14 2016 +0800 # Node ID 652843788cb08c18dcbc6bab2857a228093767e4 # Parent 56d6bfe6b609c565a9f500bde573fd9b488ff960 Core: add ngx_atosp(). This allows to correctly parse "start" and "end" arguments without null-termination (ticket #475), and also fixes rounding errors observed with strtod() when using i387 instructions. diff -r 56d6bfe6b609 -r 652843788cb0 src/core/ngx_string.c --- a/src/core/ngx_string.c Fri Oct 21 16:28:39 2016 +0300 +++ b/src/core/ngx_string.c Wed Oct 26 17:24:14 2016 +0800 @@ -926,7 +926,9 @@ } -/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */ +/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050. + * can be replaced by ngx_atosp(line, n, point, 1). + */ ngx_int_t ngx_atofp(u_char *line, size_t n, size_t point) @@ -982,6 +984,76 @@ } +/* parse a fixed point number and do bounds check when strict is true, e.g., + * ngx_atosp("12.2193", 3, 0, 0) returns 12, + * ngx_atosp("12.2193", 3, 0, 1) returns NGX_ERROR, + * ngx_atosp("12.2193", 6, 3, 1) returns 12219, + * ngx_atosp("12.2193", 7, 3, 1) returns NGX_ERROR, + * ngx_atosp("12.2193", 7, 3, 0) returns 12219. + */ + +ngx_int_t +ngx_atosp(u_char *line, size_t n, size_t point, unsigned strict) +{ + ngx_int_t value, cutoff, cutlim; + ngx_uint_t dot; + + if (n == 0) { + return NGX_ERROR; + } + + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; + + dot = 0; + + for (value = 0; n--; line++) { + + if (*line == '.') { + if (dot) { + return NGX_ERROR; + } + + if (strict && point == 0) { + return NGX_ERROR; + } + + dot = 1; + continue; + } + + if (*line < '0' || *line > '9') { + return NGX_ERROR; + } + + if (dot && point == 0) { + if (strict) { + return NGX_ERROR; + } + + continue; + } + + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + + value = value * 10 + (*line - '0'); + point -= dot; + } + + while (point--) { + if (value > cutoff) { + return NGX_ERROR; + } + + value = value * 10; + } + + return value; +} + + ssize_t ngx_atosz(u_char *line, size_t n) { diff -r 56d6bfe6b609 -r 652843788cb0 src/core/ngx_string.h --- a/src/core/ngx_string.h Fri Oct 21 16:28:39 2016 +0300 +++ b/src/core/ngx_string.h Wed Oct 26 17:24:14 2016 +0800 @@ -171,6 +171,7 @@ ngx_int_t ngx_atoi(u_char *line, size_t n); ngx_int_t ngx_atofp(u_char *line, size_t n, size_t point); +ngx_int_t ngx_atosp(u_char *line, size_t n, size_t point, unsigned strict); ssize_t ngx_atosz(u_char *line, size_t n); off_t ngx_atoof(u_char *line, size_t n); time_t ngx_atotm(u_char *line, size_t n); diff -r 56d6bfe6b609 -r 652843788cb0 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Fri Oct 21 16:28:39 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Wed Oct 26 17:24:14 2016 +0800 @@ -537,26 +537,15 @@ /* * A Flash player may send start value with a lot of digits - * after dot so strtod() is used instead of atofp(). NaNs and - * infinities become negative numbers after (int) conversion. + * after dot so ngx_atosp() is used instead of ngx_atofp(). */ - ngx_set_errno(0); - start = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - start = -1; - } + start = ngx_atosp(value.data, value.len, 3, 0); } if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) { - ngx_set_errno(0); - end = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - end = -1; - } + end = ngx_atosp(value.data, value.len, 3, 0); if (end > 0) { if (start < 0) { -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Wed Oct 26 12:31:24 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 26 Oct 2016 15:31:24 +0300 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. In-Reply-To: References: Message-ID: <20161026123124.GB73038@mdounin.ru> Hello! On Wed, Oct 26, 2016 at 05:10:25PM +0800, ?? (hucc) wrote: > On Wed, Oct 26, 2016 3:34 AM, Maxim Dounin wrote: > > >Using strtod() should be avoided as it has other problems, see > >https://trac.nginx.org/nginx/ticket/475. That is, an additional > >variant of ngx_atofp() is a way to go. > > > > > >Last time we've looked into this, we've stumbled upon selecting a > >proper name for the additional function. Looking into this again > >I tend to think that proper solution would be to use a special > >function withing the ngx_http_mp4_module itself. Patch below. > > > VOD (video on demand) module which support requesting time range > also need the special function, so i would like to see that nginx-devel > add a function in Core, that would be helpful. Possible patch below. If you mean https://github.com/kaltura/nginx-vod-module, then I don't think it does. Quick look suggests that it uses milliseconds to specify times instead, and uses ngx_atoi() to parse them. It doesn't use strtod() at all, and the only place it uses ngx_atofp() now is to parse rate, and I don't think there are reasons to allow arbitrary numbers like in the mp4 case. The main problem with mp4 was that there were existing Flash clients nginx has to be compatible with, and some of them used to send incorrect start time specifications. It is highly unlikely that the same unique situation affects other modules. -- Maxim Dounin http://nginx.org/ From hucong.c at foxmail.com Wed Oct 26 16:40:21 2016 From: hucong.c at foxmail.com (=?gb18030?B?uvq0zyAoaHVjYyk=?=) Date: Thu, 27 Oct 2016 00:40:21 +0800 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. Message-ID: Hello! On Wed, Oct 26, 2016 at 8:31PM, Maxim Dounin wrote: >On Wed, Oct 26, 2016 at 05:10:25PM +0800, ?? (hucc) wrote: > >> VOD (video on demand) module which support requesting time range >> also need the special function, so i would like to see that nginx-devel >> add a function in Core, that would be helpful. Possible patch below. > >If you mean https://github.com/kaltura/nginx-vod-module, then I >don't think it does. Quick look suggests that it uses >milliseconds to specify times instead, and uses ngx_atoi() to >parse them. It doesn't use strtod() at all, and the only place it >uses ngx_atofp() now is to parse rate, and I don't think there are >reasons to allow arbitrary numbers like in the mp4 case. > >The main problem with mp4 was that there were existing Flash >clients nginx has to be compatible with, and some of them used to >send incorrect start time specifications. It is highly unlikely >that the same unique situation affects other modules. I don`t know how to make a more specific description because of my poor english. What i mean about VOD is video-processing module in CDN provider, this scenario usually be asked to provide parameter parsing which support seconds and milliseconds. I am developing a series of moudles which are a bit like nginx-vod-module and new function will be used based on my experience. I just think the usage of atofp() is very limited, maybe a function supporting optional mode should be provided. Anyway, the point is whether other modules need new function, i pointed out the scene i familiar with and hope this helps. Regards, -hucc -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Wed Oct 26 17:32:19 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 26 Oct 2016 17:32:19 +0000 Subject: [nginx] Proxy: support variables for proxy_method directive. Message-ID: details: http://hg.nginx.org/nginx/rev/ca27074f8f0f branches: changeset: 6781:ca27074f8f0f user: Dmitry Lazurkin date: Sun Oct 16 18:24:01 2016 +0300 description: Proxy: support variables for proxy_method directive. diffstat: src/http/modules/ngx_http_proxy_module.c | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) diffs (54 lines): diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -73,7 +73,7 @@ typedef struct { ngx_array_t *cookie_domains; ngx_array_t *cookie_paths; - ngx_str_t method; + ngx_http_complex_value_t *method; ngx_str_t location; ngx_str_t url; @@ -380,7 +380,7 @@ static ngx_command_t ngx_http_proxy_com { ngx_string("proxy_method"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_http_set_complex_value_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, method), NULL }, @@ -1159,8 +1159,10 @@ ngx_http_proxy_create_request(ngx_http_r /* HEAD was changed to GET to cache response */ method = u->method; - } else if (plcf->method.len) { - method = plcf->method; + } else if (plcf->method) { + if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) { + return NGX_ERROR; + } } else { method = r->method_name; @@ -2797,7 +2799,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ * conf->upstream.store_values = NULL; * conf->upstream.ssl_name = NULL; * - * conf->method = { 0, NULL }; + * conf->method = NULL; * conf->headers_source = NULL; * conf->headers.lengths = NULL; * conf->headers.values = NULL; @@ -3158,7 +3160,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t #endif - ngx_conf_merge_str_value(conf->method, prev->method, ""); + if (conf->method == NULL) { + conf->method = prev->method; + } ngx_conf_merge_value(conf->upstream.pass_request_headers, prev->upstream.pass_request_headers, 1); From mdounin at mdounin.ru Wed Oct 26 17:32:32 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 26 Oct 2016 20:32:32 +0300 Subject: [PATCH] [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: <9fbfc0ccb28e1eee624f.1477085476@user-notebook> References: <41dc35ff-49c1-afde-81b6-a17d7bc0fda5@gmail.com> <9fbfc0ccb28e1eee624f.1477085476@user-notebook> Message-ID: <20161026173232.GG73038@mdounin.ru> Hello! On Sat, Oct 22, 2016 at 12:31:16AM +0300, dilaz03 at gmail.com wrote: > # HG changeset patch > # User Dmitry Lazurkin > # Date 1476631441 -10800 > # Sun Oct 16 18:24:01 2016 +0300 > # Node ID 9fbfc0ccb28e1eee624ff212de88fa1c051f09d9 > # Parent 56d6bfe6b609c565a9f500bde573fd9b488ff960 > Proxy: support variables for proxy_method directive. > > diff -r 56d6bfe6b609 -r 9fbfc0ccb28e src/http/modules/ngx_http_proxy_module.c > --- a/src/http/modules/ngx_http_proxy_module.c Fri Oct 21 16:28:39 2016 +0300 > +++ b/src/http/modules/ngx_http_proxy_module.c Sun Oct 16 18:24:01 2016 +0300 > @@ -73,7 +73,7 @@ > ngx_array_t *cookie_domains; > ngx_array_t *cookie_paths; > > - ngx_str_t method; > + ngx_http_complex_value_t *method; > ngx_str_t location; > ngx_str_t url; > > @@ -380,7 +380,7 @@ > > { ngx_string("proxy_method"), > NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, > - ngx_conf_set_str_slot, > + ngx_http_set_complex_value_slot, > NGX_HTTP_LOC_CONF_OFFSET, > offsetof(ngx_http_proxy_loc_conf_t, method), > NULL }, > @@ -1159,8 +1159,10 @@ > /* HEAD was changed to GET to cache response */ > method = u->method; > > - } else if (plcf->method.len) { > - method = plcf->method; > + } else if (plcf->method != NULL) { > + if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) { > + return NGX_ERROR; > + } > > } else { > method = r->method_name; > @@ -3158,7 +3160,9 @@ > > #endif > > - ngx_conf_merge_str_value(conf->method, prev->method, ""); > + if (conf->method == NULL) { > + conf->method = prev->method; > + } > > ngx_conf_merge_value(conf->upstream.pass_request_headers, > prev->upstream.pass_request_headers, 1); Looks good, except a few style nits: - We don't usually check pointers with "!= NULL", just testing "if (plcf->method)" would be enough here. - You've forgot to update the "set by ngx_pcalloc()" comment in ngx_http_proxy_create_loc_conf(). Committed with the following patch on top: --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1159,7 +1159,7 @@ ngx_http_proxy_create_request(ngx_http_r /* HEAD was changed to GET to cache response */ method = u->method; - } else if (plcf->method != NULL) { + } else if (plcf->method) { if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) { return NGX_ERROR; } @@ -2799,7 +2799,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ * conf->upstream.store_values = NULL; * conf->upstream.ssl_name = NULL; * - * conf->method = { 0, NULL }; + * conf->method = NULL; * conf->headers_source = NULL; * conf->headers.lengths = NULL; * conf->headers.values = NULL; Thanks! -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Oct 26 17:38:05 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 26 Oct 2016 20:38:05 +0300 Subject: [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: <6f0d1849-460d-e2a7-1d1e-b96143e5f9f1@gmail.com> References: <6f0d1849-460d-e2a7-1d1e-b96143e5f9f1@gmail.com> Message-ID: <20161026173804.GH73038@mdounin.ru> Hello! On Fri, Oct 21, 2016 at 11:53:11PM +0300, Dmitry Lazurkin wrote: > Add more tests. > > # HG changeset patch > # User Dmitry Lazurkin > # Date 1476632999 -10800 > # Sun Oct 16 18:49:59 2016 +0300 > # Node ID 916ac83eed31a4e7f6f303e28867b925fc62bc27 > # Parent 1b11a12be17913a75e81d318dcb6b912eac5f29e > Tests: add tests for proxy_method directive. > > diff -r 1b11a12be179 -r 916ac83eed31 proxy_method.t > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/proxy_method.t Sun Oct 16 18:49:59 2016 +0300 > @@ -0,0 +1,86 @@ > +#!/usr/bin/perl > + > +# (C) Dmitry Lazurkin > + > +# Tests for proxy_method. > + > +############################################################################### > + > +use warnings; > +use strict; > + > +use Test::More; > + > +BEGIN { use FindBin; chdir($FindBin::Bin); } > + > +use lib 'lib'; > +use Test::Nginx; > + > +############################################################################### > + > +select STDERR; $| = 1; > +select STDOUT; $| = 1; > + > +my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(4) > + ->write_file_expand('nginx.conf', <<'EOF'); > + > +%%TEST_GLOBALS%% > + > +daemon off; > + > +events { > +} > + > +http { > + %%TEST_GLOBALS_HTTP%% > + > + server { > + listen 127.0.0.1:8080; > + server_name localhost; > + > + location /preserve { > + proxy_pass http://127.0.0.1:8080/get-method; > + } > + > + location /const { > + proxy_pass http://127.0.0.1:8080/get-method; > + proxy_method POST; > + } > + > + location /var { > + proxy_pass http://127.0.0.1:8080/get-method; > + proxy_method $arg_method; > + } > + > + location /parent { > + proxy_method POST; > + location /parent/child { > + proxy_pass http://127.0.0.1:8080/get-method; > + } > + } > + > + location /get-method { > + return 200 "request_method=$request_method"; > + } > + } > +} > + > +EOF > + > +$t->run(); > + > +############################################################################### > + > +like(http_get('/preserve'), qr/request_method=GET/, > + 'proxy_method from request'); > + > +like(http_get('/const'), qr/request_method=POST/, > + 'proxy_method from constant'); > + > +like(http_get('/var?method=POST'), qr/request_method=POST/, > + 'proxy_method from variable'); > + > +like(http_get('/parent/child'), qr/request_method=POST/, > + 'proxy_method from parent'); > + > +############################################################################### Such a test will fail on versions without variables support in proxy_method. This is a problem, as the same test suite is used to test both mainline and stable. To address this we use conditional TODO tests with version checked: diff --git a/proxy_method.t b/proxy_method.t --- a/proxy_method.t +++ b/proxy_method.t @@ -77,9 +77,14 @@ like(http_get('/preserve'), qr/request_m like(http_get('/const'), qr/request_method=POST/, 'proxy_method from constant'); +TODO: { +local $TODO = 'not yet' unless $t->has_version('1.11.6'); + like(http_get('/var?method=POST'), qr/request_method=POST/, 'proxy_method from variable'); +} + like(http_get('/parent/child'), qr/request_method=POST/, 'proxy_method from parent'); Additionally, style is slighly different in our test scripts for historical reasons, tabs are used to indent perl code. Committed with the above changes, thanks. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Oct 26 17:56:52 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 26 Oct 2016 20:56:52 +0300 Subject: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem. In-Reply-To: References: Message-ID: <20161026175652.GI73038@mdounin.ru> Hello! On Thu, Oct 27, 2016 at 12:40:21AM +0800, ?? (hucc) wrote: > Hello! > > On Wed, Oct 26, 2016 at 8:31PM, Maxim Dounin wrote: > > >On Wed, Oct 26, 2016 at 05:10:25PM +0800, ?? (hucc) wrote: > > > >> VOD (video on demand) module which support requesting time range > >> also need the special function, so i would like to see that nginx-devel > >> add a function in Core, that would be helpful. Possible patch below. > > > >If you mean https://github.com/kaltura/nginx-vod-module, then I > >don't think it does. Quick look suggests that it uses > >milliseconds to specify times instead, and uses ngx_atoi() to > >parse them. It doesn't use strtod() at all, and the only place it > >uses ngx_atofp() now is to parse rate, and I don't think there are > >reasons to allow arbitrary numbers like in the mp4 case. > > > >The main problem with mp4 was that there were existing Flash > >clients nginx has to be compatible with, and some of them used to > >send incorrect start time specifications. It is highly unlikely > >that the same unique situation affects other modules. > > I don`t know how to make a more specific description because of my > poor english. What i mean about VOD is video-processing module in > CDN provider, this scenario usually be asked to provide parameter > parsing which support seconds and milliseconds. I am developing a > series of moudles which are a bit like nginx-vod-module and new > function will be used based on my experience. I just think the usage > of atofp() is very limited, maybe a function supporting optional mode > should be provided. Anyway, the point is whether other modules > need new function, i pointed out the scene i familiar with and hope > this helps. There is no problem with parsing seconds and milliseconds using ngx_atofp(). The problem with ngx_atofp() only appears if you have to support existing clients who already use invalid syntax. Unless you have to support such clients - you'd better use generic ngx_atofp() and reject attempts to use invalid syntax in the arguments. -- Maxim Dounin http://nginx.org/ From hongzhidao at gmail.com Thu Oct 27 03:37:16 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Thu, 27 Oct 2016 11:37:16 +0800 Subject: [nginx] tiny style Message-ID: Hi! static ngx_int_t ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data) { ngx_http_limit_req_ctx_t *octx = data; size_t len; ngx_http_limit_req_ctx_t *ctx; ctx = shm_zone->data; if (octx) { if (ctx->key.value.len != octx->key.value.len || ngx_strncmp(ctx->key.value.data, octx->key.value.data, ctx->key.value.len) != 0) { ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, - "limit_req \"%V\" uses the \"%V\" key " + "limit_req_zone \"%V\" uses the \"%V\" key " "while previously it used the \"%V\" key", &shm_zone->shm.name, &ctx->key.value, &octx->key.value); return NGX_ERROR; } ... } B.R~ -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Thu Oct 27 09:51:47 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 27 Oct 2016 09:51:47 +0000 Subject: [njs] String.prototype.indexOf() method fixes. Message-ID: details: http://hg.nginx.org/njs/rev/74785cebd8df branches: changeset: 222:74785cebd8df user: Igor Sysoev date: Thu Oct 27 10:47:48 2016 +0300 description: String.prototype.indexOf() method fixes. diffstat: njs/njs_string.c | 66 +++++++++++++++++++++++++++++++++++++++++------ njs/test/njs_unit_test.c | 6 ++++ 2 files changed, 63 insertions(+), 9 deletions(-) diffs (104 lines): diff -r f21747d5ac83 -r 74785cebd8df njs/njs_string.c --- a/njs/njs_string.c Tue Oct 25 17:52:18 2016 +0300 +++ b/njs/njs_string.c Thu Oct 27 10:47:48 2016 +0300 @@ -1212,24 +1212,72 @@ static njs_ret_t njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - ssize_t start, index; - - index = -1; + ssize_t index, length, search_length; + const u_char *p, *end; + njs_string_prop_t string, search; if (nargs > 1) { - start = 0; + 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) { - start = args[2].data.u.number; - - if (start < 0) { - start = 0; + index = args[2].data.u.number; + + if (index < 0) { + index = 0; } } - index = njs_string_index_of(vm, &args[0], &args[1], start); + if (index < length) { + end = string.start + string.size; + + if (string.size == (size_t) length) { + /* Byte or ASCII string. */ + + end -= (search.size - 1); + + for (p = string.start + index; p < end; p++) { + if (memcmp(p, search.start, search.size) == 0) { + goto done; + } + + index++; + } + + } else { + /* UTF-8 string. */ + + p = njs_string_offset(string.start, end, index); + end -= search.size - 1; + + while (p < end) { + if (memcmp(p, search.start, search.size) == 0) { + goto done; + } + + index++; + p = nxt_utf8_next(p, end); + } + } + + } else if (search.size == 0) { + index = length; + goto done; + } } +small: + + index = -1; + +done: + njs_number_set(&vm->retval, index); return NXT_OK; diff -r f21747d5ac83 -r 74785cebd8df njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Oct 25 17:52:18 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Oct 27 10:47:48 2016 +0300 @@ -3212,9 +3212,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("'12345'.indexOf()"), nxt_string("-1") }, + { nxt_string("''.indexOf('')"), + nxt_string("0") }, + { nxt_string("'12345'.indexOf(45, '0')"), nxt_string("3") }, + { nxt_string("'12'.indexOf('12345')"), + nxt_string("-1") }, + { nxt_string("''.indexOf.call(12345, 45, '0')"), nxt_string("3") }, From igor at sysoev.ru Thu Oct 27 09:51:54 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 27 Oct 2016 09:51:54 +0000 Subject: [njs] String.prototype.lastIndexOf() method fixes and optimizati... Message-ID: details: http://hg.nginx.org/njs/rev/da63e61ecef4 branches: changeset: 223:da63e61ecef4 user: Igor Sysoev date: Thu Oct 27 10:56:54 2016 +0300 description: String.prototype.lastIndexOf() method fixes and optimizations. In collaboration with Valentin Bartenev. diffstat: njs/njs_string.c | 129 ++++++++++++++++++++++------------------------ njs/test/njs_unit_test.c | 41 ++++++++++++++- nxt/nxt_utf8.h | 27 ++++++++- 3 files changed, 123 insertions(+), 74 deletions(-) diffs (274 lines): diff -r 74785cebd8df -r da63e61ecef4 njs/njs_string.c --- a/njs/njs_string.c Thu Oct 27 10:47:48 2016 +0300 +++ b/njs/njs_string.c Thu Oct 27 10:56:54 2016 +0300 @@ -83,8 +83,6 @@ 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 nxt_noinline ssize_t njs_string_index_of(njs_vm_t *vm, - njs_value_t *src, njs_value_t *search_string, size_t index); 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, @@ -1288,91 +1286,86 @@ static njs_ret_t njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - ssize_t ret, index, last; - - index = -1; - - if (nargs > 1) { - last = NJS_STRING_MAX_LENGTH; - - if (nargs > 2) { - last = args[2].data.u.number; - - if (last < 0) { - last = 0; - } - } - - ret = 0; - - for ( ;; ) { - ret = njs_string_index_of(vm, &args[0], &args[1], ret); - - if (ret < 0 || ret >= last) { - break; - } - - index = ret++; - } - } - - njs_number_set(&vm->retval, index); - - return NXT_OK; -} - - -static nxt_noinline ssize_t -njs_string_index_of(njs_vm_t *vm, njs_value_t *src, njs_value_t *search_string, - size_t index) -{ - size_t length; + ssize_t index, start, length, search_length; const u_char *p, *end; njs_string_prop_t string, search; - (void) njs_string_prop(&search, search_string); - - length = njs_string_prop(&string, src); - - if (index < length) { - - if (string.size == length) { + if (nargs > 1) { + length = njs_string_prop(&string, &args[0]); + search_length = njs_string_prop(&search, &args[1]); + + if (length < search_length) { + goto small; + } + + index = NJS_STRING_MAX_LENGTH; + + if (nargs > 2) { + index = args[2].data.u.number; + + if (index < 0) { + index = 0; + } + } + + if (index > length) { + index = length; + } + + if (string.size == (size_t) length) { /* Byte or ASCII string. */ + + start = length - search.size; + + if (index > start) { + index = start; + } + p = string.start + index; - end = (string.start + string.size) - (search.size - 1); - - while (p < end) { + + do { if (memcmp(p, search.start, search.size) == 0) { - return index; + goto done; } - index++; - p++; - } + p--; + index--; + + } while (index >= 0); } else { /* UTF-8 string. */ + end = string.start + string.size; - p = njs_string_offset(string.start, end, index); - - end -= search.size - 1; - - while (p < end) { + end -= search.size; + + while (p > end) { + index--; + p = nxt_utf8_prev(p); + } + + do { if (memcmp(p, search.start, search.size) == 0) { - return index; + goto done; } - index++; - p = nxt_utf8_next(p, end); - } + p = nxt_utf8_prev(p); + index--; + + } while (index >= 0); } - - } else if (search.size == 0) { - return length; } - return -1; +small: + + index = -1; + +done: + + njs_number_set(&vm->retval, index); + + return NXT_OK; } diff -r 74785cebd8df -r da63e61ecef4 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Oct 27 10:47:48 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Oct 27 10:56:54 2016 +0300 @@ -3224,6 +3224,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("''.indexOf.call(12345, 45, '0')"), nxt_string("3") }, + { nxt_string("'abc'.lastIndexOf('abcdef')"), + nxt_string("-1") }, + { nxt_string("'abc abc abc abc'.lastIndexOf('abc')"), nxt_string("12") }, @@ -3231,7 +3234,43 @@ static njs_unit_test_t njs_test[] = nxt_string("8") }, { nxt_string("'abc abc abc abc'.lastIndexOf('abc', 0)"), - nxt_string("-1") }, + nxt_string("0") }, + + { nxt_string("'abc abc abc abc'.lastIndexOf('', 0)"), + nxt_string("0") }, + + { nxt_string("'abc abc abc abc'.lastIndexOf('', 5)"), + nxt_string("5") }, + + { nxt_string("'abc abc ????? abc'.lastIndexOf('?????')"), + nxt_string("8") }, + + { nxt_string("'abc abc ????????'.lastIndexOf('?????')"), + nxt_string("8") }, + + { nxt_string("'abc abc ????????'.lastIndexOf('?????', 11)"), + nxt_string("8") }, + + { nxt_string("'abc abc ????????'.lastIndexOf('?????', 12)"), + nxt_string("8") }, + + { nxt_string("'abc abc ????????'.lastIndexOf('?????', 13)"), + nxt_string("8") }, + + { nxt_string("'abc abc ????????'.lastIndexOf('?????', 14)"), + nxt_string("8") }, + + { nxt_string("'abc abc ????????'.lastIndexOf('?????', 15)"), + nxt_string("8") }, + + { nxt_string("'abc abc ????????'.lastIndexOf('')"), + nxt_string("16") }, + + { nxt_string("'abc abc ????????'.lastIndexOf('', 12)"), + nxt_string("12") }, + + { nxt_string("''.lastIndexOf('')"), + nxt_string("0") }, { nxt_string("'ABC'.toLowerCase()"), nxt_string("abc") }, diff -r 74785cebd8df -r da63e61ecef4 nxt/nxt_utf8.h --- a/nxt/nxt_utf8.h Thu Oct 27 10:47:48 2016 +0300 +++ b/nxt/nxt_utf8.h Thu Oct 27 10:56:54 2016 +0300 @@ -29,7 +29,12 @@ NXT_EXPORT ssize_t nxt_utf8_length(const NXT_EXPORT nxt_bool_t nxt_utf8_is_valid(const u_char *p, size_t len); -/* nxt_utf8_next() expects a valid UTF-8 string. */ +/* + * nxt_utf8_next() and nxt_utf8_prev() expect a valid UTF-8 string. + * + * The leading UTF-8 byte is either 0xxxxxxx or 11xxxxxx. + * The continuation UTF-8 bytes are 10xxxxxx. + */ nxt_inline const u_char * nxt_utf8_next(const u_char *p, const u_char *end) @@ -41,10 +46,6 @@ nxt_utf8_next(const u_char *p, const u_c if ((c & 0x80) != 0) { do { - /* - * The first UTF-8 byte is either 0xxxxxxx or 11xxxxxx. - * The next UTF-8 bytes are 10xxxxxx. - */ c = *p; if ((c & 0xC0) != 0x80) { @@ -60,6 +61,22 @@ nxt_utf8_next(const u_char *p, const u_c } +nxt_inline const u_char * +nxt_utf8_prev(const u_char *p) +{ + u_char c; + + do { + p--; + c = *p; + + } while ((c & 0xC0) == 0x80); + + return p; +} + + + #define nxt_utf8_size(u) \ ((u < 0x80) ? 1 : ((u < 0x0800) ? 2 : ((u < 0x10000) ? 3 : 4))) From igor at sysoev.ru Thu Oct 27 09:51:55 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 27 Oct 2016 09:51:55 +0000 Subject: [njs] String.prototypes.includes() method. Message-ID: details: http://hg.nginx.org/njs/rev/86fd59307356 branches: changeset: 224:86fd59307356 user: Igor Sysoev date: Thu Oct 27 11:14:46 2016 +0300 description: String.prototypes.includes() method. diffstat: njs/njs_string.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 18 +++++++++++ 2 files changed, 96 insertions(+), 0 deletions(-) diffs (123 lines): diff -r da63e61ecef4 -r 86fd59307356 njs/njs_string.c --- a/njs/njs_string.c Thu Oct 27 10:56:54 2016 +0300 +++ b/njs/njs_string.c Thu Oct 27 11:14:46 2016 +0300 @@ -1369,6 +1369,76 @@ done: } +static njs_ret_t +njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + 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]); + + if (length < search_length) { + goto small; + } + + index = 0; + + if (nargs > 2) { + index = args[2].data.u.number; + + if (index < 0) { + index = 0; + } + } + + if (index < length) { + 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); + } + + end -= search.size - 1; + + while (p < end) { + if (memcmp(p, search.start, search.size) == 0) { + goto done; + } + + p++; + } + } + } + +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. @@ -2812,6 +2882,14 @@ 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("includes"), + .value = njs_native_function(njs_string_prototype_includes, 0, + NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("toLowerCase"), diff -r da63e61ecef4 -r 86fd59307356 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Oct 27 10:56:54 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Oct 27 11:14:46 2016 +0300 @@ -3272,6 +3272,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("''.lastIndexOf('')"), nxt_string("0") }, + { nxt_string("''.includes('')"), + nxt_string("true") }, + + { nxt_string("'12345'.includes()"), + nxt_string("false") }, + + { nxt_string("'?????????????????????????????????'.includes('????', 10)"), + nxt_string("true") }, + + { nxt_string("'??? ??? ????????'.includes('?????', 7)"), + nxt_string("true") }, + + { nxt_string("'??? ??? ????????'.includes('?????', 8)"), + nxt_string("true") }, + + { nxt_string("'??? ??? ????????'.includes('?????', 9)"), + nxt_string("false") }, + { nxt_string("'ABC'.toLowerCase()"), nxt_string("abc") }, From igor at sysoev.ru Thu Oct 27 13:50:15 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 27 Oct 2016 13:50:15 +0000 Subject: [njs] String.prototype.lastIndexOf() method fix. Message-ID: details: http://hg.nginx.org/njs/rev/d84e34c2dbde branches: changeset: 225:d84e34c2dbde user: Igor Sysoev date: Thu Oct 27 16:38:05 2016 +0300 description: String.prototype.lastIndexOf() method fix. In collaboration with Valentin Bartenev. diffstat: njs/njs_string.c | 24 +++++++++++++----------- 1 files changed, 13 insertions(+), 11 deletions(-) diffs (63 lines): diff -r 86fd59307356 -r d84e34c2dbde njs/njs_string.c --- a/njs/njs_string.c Thu Oct 27 11:14:46 2016 +0300 +++ b/njs/njs_string.c Thu Oct 27 16:38:05 2016 +0300 @@ -1290,12 +1290,14 @@ njs_string_prototype_last_index_of(njs_v const u_char *p, *end; njs_string_prop_t string, search; + index = -1; + if (nargs > 1) { length = njs_string_prop(&string, &args[0]); search_length = njs_string_prop(&search, &args[1]); if (length < search_length) { - goto small; + goto done; } index = NJS_STRING_MAX_LENGTH; @@ -1328,10 +1330,10 @@ njs_string_prototype_last_index_of(njs_v goto done; } - p--; index--; - - } while (index >= 0); + p--; + + } while (p >= string.start); } else { /* UTF-8 string. */ @@ -1345,22 +1347,22 @@ njs_string_prototype_last_index_of(njs_v p = nxt_utf8_prev(p); } - do { + for ( ;; ) { if (memcmp(p, search.start, search.size) == 0) { goto done; } - p = nxt_utf8_prev(p); index--; - } while (index >= 0); + if (p <= string.start) { + break; + } + + p = nxt_utf8_prev(p); + } } } -small: - - index = -1; - done: njs_number_set(&vm->retval, index); From konstantin at linux-admins.net Thu Oct 27 15:04:52 2016 From: konstantin at linux-admins.net (Ivanov, Konstantin) Date: Thu, 27 Oct 2016 10:04:52 -0500 Subject: PROXY support in the ngx_mail_proxy_module Message-ID: Hello, We are using nginx behind an ELB with PROXY protocol enabled and the mail module. After going though the code it became apparent that the mail module we use in nginx to proxy to our upstream mail applications does not support the PROXY command and it just returns a 500 from https://github.com/nginx/ nginx/blob/master/src/mail/ngx_mail_smtp_handler.c#L43. Is there a reason why the mail module does not support the PROXY protocol? It seems rather trivial to implement it in https://github.com/nginx/ nginx/blob/master/src/mail/ngx_mail.h#L153 and further up the chain. We could probably use the stream module instead, but we use starttls and auth in the mail module. Cheers! -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Oct 27 15:05:38 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 27 Oct 2016 15:05:38 +0000 Subject: [nginx] Mp4: introduced custom version of ngx_atofp(). Message-ID: details: http://hg.nginx.org/nginx/rev/b123eae3fd4e branches: changeset: 6782:b123eae3fd4e user: Maxim Dounin date: Thu Oct 27 17:57:16 2016 +0300 description: Mp4: introduced custom version of ngx_atofp(). This allows to correctly parse "start" and "end" arguments without null-termination (ticket #475), and also fixes rounding errors observed with strtod() when using i387 instructions. diffstat: src/http/modules/ngx_http_mp4_module.c | 74 +++++++++++++++++++++++++++------ 1 files changed, 60 insertions(+), 14 deletions(-) diffs (104 lines): diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c +++ b/src/http/modules/ngx_http_mp4_module.c @@ -216,6 +216,7 @@ typedef struct { static ngx_int_t ngx_http_mp4_handler(ngx_http_request_t *r); +static ngx_int_t ngx_http_mp4_atofp(u_char *line, size_t n, size_t point); static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4); static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4, @@ -537,26 +538,15 @@ ngx_http_mp4_handler(ngx_http_request_t /* * A Flash player may send start value with a lot of digits - * after dot so strtod() is used instead of atofp(). NaNs and - * infinities become negative numbers after (int) conversion. + * after dot so a custom function is used instead of ngx_atofp(). */ - ngx_set_errno(0); - start = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - start = -1; - } + start = ngx_http_mp4_atofp(value.data, value.len, 3); } if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) { - ngx_set_errno(0); - end = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - end = -1; - } + end = ngx_http_mp4_atofp(value.data, value.len, 3); if (end > 0) { if (start < 0) { @@ -687,6 +677,62 @@ ngx_http_mp4_handler(ngx_http_request_t static ngx_int_t +ngx_http_mp4_atofp(u_char *line, size_t n, size_t point) +{ + ngx_int_t value, cutoff, cutlim; + ngx_uint_t dot; + + /* same as ngx_atofp(), but allows additional digits */ + + if (n == 0) { + return NGX_ERROR; + } + + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; + + dot = 0; + + for (value = 0; n--; line++) { + + if (*line == '.') { + if (dot) { + return NGX_ERROR; + } + + dot = 1; + continue; + } + + if (*line < '0' || *line > '9') { + return NGX_ERROR; + } + + if (point == 0) { + continue; + } + + if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { + return NGX_ERROR; + } + + value = value * 10 + (*line - '0'); + point -= dot; + } + + while (point--) { + if (value > cutoff) { + return NGX_ERROR; + } + + value = value * 10; + } + + return value; +} + + +static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4) { off_t start_offset, end_offset, adjustment; From piotrsikora at google.com Fri Oct 28 05:58:27 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 27 Oct 2016 22:58:27 -0700 Subject: [PATCH] Add missing includes Message-ID: <5b770255cfd18765a881.1477634307@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1477633918 25200 # Thu Oct 27 22:51:58 2016 -0700 # Node ID 5b770255cfd18765a88147910255735ed2966b4e # Parent d84e34c2dbde138ebd06b77bbe5b9ee2f1f62f05 Add missing includes. Previously, most objects were compiled without any features detected by the ./configure script. Signed-off-by: Piotr Sikora diff -r d84e34c2dbde -r 5b770255cfd1 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c +++ b/nginx/ngx_stream_js_module.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_array.c --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_boolean.c --- a/njs/njs_boolean.c +++ b/njs/njs_boolean.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_builtin.c --- a/njs/njs_builtin.c +++ b/njs/njs_builtin.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_disassembler.c --- a/njs/njs_disassembler.c +++ b/njs/njs_disassembler.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_extern.c --- a/njs/njs_extern.c +++ b/njs/njs_extern.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_function.c --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_generator.c --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_lexer.c --- a/njs/njs_lexer.c +++ b/njs/njs_lexer.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c +++ b/njs/njs_lexer_keyword.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_math.c --- a/njs/njs_math.c +++ b/njs/njs_math.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_number.c --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_object.c --- a/njs/njs_object.c +++ b/njs/njs_object.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_parser.c --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_variable.c --- a/njs/njs_variable.c +++ b/njs/njs_variable.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njs_vm.c --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/njscript.c --- a/njs/njscript.c +++ b/njs/njscript.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_array.c --- a/nxt/nxt_array.c +++ b/nxt/nxt_array.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_djb_hash.c --- a/nxt/nxt_djb_hash.c +++ b/nxt/nxt_djb_hash.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_lvlhsh.c --- a/nxt/nxt_lvlhsh.c +++ b/nxt/nxt_lvlhsh.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_mem_cache_pool.c --- a/nxt/nxt_mem_cache_pool.c +++ b/nxt/nxt_mem_cache_pool.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_murmur_hash.c --- a/nxt/nxt_murmur_hash.c +++ b/nxt/nxt_murmur_hash.c @@ -4,6 +4,7 @@ * released to the public domain. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_pcre.c --- a/nxt/nxt_pcre.c +++ b/nxt/nxt_pcre.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_queue.c --- a/nxt/nxt_queue.c +++ b/nxt/nxt_queue.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_random.c --- a/nxt/nxt_random.c +++ b/nxt/nxt_random.c @@ -5,6 +5,7 @@ */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_rbtree.c --- a/nxt/nxt_rbtree.c +++ b/nxt/nxt_rbtree.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/nxt_utf8.c --- a/nxt/nxt_utf8.c +++ b/nxt/nxt_utf8.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/test/lvlhsh_unit_test.c --- a/nxt/test/lvlhsh_unit_test.c +++ b/nxt/test/lvlhsh_unit_test.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/test/random_unit_test.c --- a/nxt/test/random_unit_test.c +++ b/nxt/test/random_unit_test.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/test/rbtree_unit_test.c --- a/nxt/test/rbtree_unit_test.c +++ b/nxt/test/rbtree_unit_test.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r d84e34c2dbde -r 5b770255cfd1 nxt/test/utf8_unit_test.c --- a/nxt/test/utf8_unit_test.c +++ b/nxt/test/utf8_unit_test.c @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include From piotrsikora at google.com Fri Oct 28 05:58:52 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 27 Oct 2016 22:58:52 -0700 Subject: [PATCH] Configure: fix build with -Werror=old-style-definition Message-ID: <8c0a1c8183a2811ebde2.1477634332@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1477634184 25200 # Thu Oct 27 22:56:24 2016 -0700 # Node ID 8c0a1c8183a2811ebde2823144b5ea3bb25bec80 # Parent d84e34c2dbde138ebd06b77bbe5b9ee2f1f62f05 Configure: fix build with -Werror=old-style-definition. Signed-off-by: Piotr Sikora diff -r d84e34c2dbde -r 8c0a1c8183a2 nxt/test/random_unit_test.c --- a/nxt/test/random_unit_test.c +++ b/nxt/test/random_unit_test.c @@ -14,7 +14,7 @@ static nxt_int_t -random_unit_test() +random_unit_test(void) { nxt_uint_t n; nxt_random_t r; From piotrsikora at google.com Fri Oct 28 06:03:11 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 27 Oct 2016 23:03:11 -0700 Subject: [PATCH] Configure: fix build with -Werror=old-style-definition In-Reply-To: <8c0a1c8183a2811ebde2.1477634332@piotrsikora.sfo.corp.google.com> References: <8c0a1c8183a2811ebde2.1477634332@piotrsikora.sfo.corp.google.com> Message-ID: Hey Igor, > # HG changeset patch > # User Piotr Sikora > # Date 1477634184 25200 > # Thu Oct 27 22:56:24 2016 -0700 > # Node ID 8c0a1c8183a2811ebde2823144b5ea3bb25bec80 > # Parent d84e34c2dbde138ebd06b77bbe5b9ee2f1f62f05 > Configure: fix build with -Werror=old-style-definition. > > Signed-off-by: Piotr Sikora It looks that I've missed tests last time, sorry! Best regards, Piotr Sikora From hucong.c at foxmail.com Fri Oct 28 08:41:49 2016 From: hucong.c at foxmail.com (=?gb18030?B?uvq0zyAoaHVjYyk=?=) Date: Fri, 28 Oct 2016 16:41:49 +0800 Subject: [PATCH] Event pipe: delete useless code. Message-ID: Hello! It is useless code. There is no need to judge whether the first buf is partially filled, just add the free buf after the head. # HG changeset patch # User hucongcong # Date 1477643468 -28800 # Fri Oct 28 16:31:08 2016 +0800 # Node ID 6729731c835d800aa690d8d3a362b0c989885ab3 # Parent b123eae3fd4e72e430247690e0cec5838b546055 Event pipe: delete useless code. diff -r b123eae3fd4e -r 6729731c835d src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c Thu Oct 27 17:57:16 2016 +0300 +++ b/src/event/ngx_event_pipe.c Fri Oct 28 16:31:08 2016 +0800 @@ -1037,17 +1037,7 @@ return NGX_OK; } - if (p->free_raw_bufs->buf->pos == p->free_raw_bufs->buf->last) { - - /* add the free buf to the list start */ - - cl->next = p->free_raw_bufs; - p->free_raw_bufs = cl; - - return NGX_OK; - } - - /* the first free buf is partially filled, thus add the free buf after it */ + /* the first buf might be partially filled, thus add the free buf after it */ cl->next = p->free_raw_bufs->next; p->free_raw_bufs->next = cl; -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Fri Oct 28 10:37:42 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 28 Oct 2016 10:37:42 +0000 Subject: [njs] String.prototype.trim() method. Message-ID: details: http://hg.nginx.org/njs/rev/5de122a4031a branches: changeset: 226:5de122a4031a user: Igor Sysoev date: Fri Oct 28 13:32:33 2016 +0300 description: String.prototype.trim() method. In collaboration with Valentin Bartenev. diffstat: njs/njs_string.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 30 ++++++++++ 2 files changed, 166 insertions(+), 0 deletions(-) diffs (193 lines): diff -r d84e34c2dbde -r 5de122a4031a njs/njs_string.c --- a/njs/njs_string.c Thu Oct 27 16:38:05 2016 +0300 +++ b/njs/njs_string.c Fri Oct 28 13:32:33 2016 +0300 @@ -1614,6 +1614,135 @@ njs_string_prototype_to_upper_case(njs_v } +static njs_ret_t +njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + uint32_t u, trim, length; + const u_char *p, *prev, *start, *end; + njs_string_prop_t string; + + trim = 0; + + njs_string_prop(&string, &args[0]); + + p = string.start; + end = string.start + string.size; + + if (string.length == 0 || string.length == string.size) { + /* Byte or ASCII string. */ + + while (p < end) { + + switch (*p) { + case 0x09: /* */ + case 0x0A: /* */ + case 0x0B: /* */ + case 0x0C: /* */ + case 0x0D: /* */ + case 0x20: /* */ + case 0xA0: /* */ + trim++; + p++; + continue; + + default: + start = p; + p = end; + + for ( ;; ) { + p--; + + switch (*p) { + case 0x09: /* */ + case 0x0A: /* */ + case 0x0B: /* */ + case 0x0C: /* */ + case 0x0D: /* */ + case 0x20: /* */ + case 0xA0: /* */ + trim++; + continue; + + default: + p++; + goto done; + } + } + } + } + + } else { + /* UTF-8 string. */ + + while (p < end) { + prev = p; + u = nxt_utf8_decode(&p, end); + + switch (u) { + case 0x0009: /* */ + case 0x000A: /* */ + case 0x000B: /* */ + case 0x000C: /* */ + case 0x000D: /* */ + case 0x0020: /* */ + case 0x00A0: /* */ + case 0x2028: /* */ + case 0x2029: /* */ + case 0xFEFF: /* */ + trim++; + continue; + + default: + start = prev; + prev = end; + + for ( ;; ) { + prev = nxt_utf8_prev(prev); + p = prev; + u = nxt_utf8_decode(&p, end); + + switch (u) { + case 0x0009: /* */ + case 0x000A: /* */ + case 0x000B: /* */ + case 0x000C: /* */ + case 0x000D: /* */ + case 0x0020: /* */ + case 0x00A0: /* */ + case 0x2028: /* */ + case 0x2029: /* */ + case 0xFEFF: /* */ + trim++; + continue; + + default: + goto done; + } + } + } + } + } + + vm->retval = njs_string_empty; + + return NXT_OK; + +done: + + if (trim == 0) { + /* GC: retain. */ + vm->retval = args[0]; + + return NXT_OK; + } + + length = (string.length != 0) ? string.length - trim : 0; + + return njs_string_new(vm, &vm->retval, start, p - start, length); +} + + /* * String.search([regexp]) */ @@ -2908,6 +3037,13 @@ static const njs_object_prop_t njs_stri { .type = NJS_METHOD, + .name = njs_string("trim"), + .value = njs_native_function(njs_string_prototype_trim, 0, + NJS_STRING_OBJECT_ARG), + }, + + { + .type = NJS_METHOD, .name = njs_string("search"), .value = njs_native_function(njs_string_prototype_search, 0, NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG), diff -r d84e34c2dbde -r 5de122a4031a njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Oct 27 16:38:05 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Oct 28 13:32:33 2016 +0300 @@ -3326,6 +3326,36 @@ static njs_unit_test_t njs_test[] = "} a"), nxt_string("304,453,456,459,498,1012,7838,8486,8490,8491") }, + { nxt_string("'abc'.trim()"), + nxt_string("abc") }, + + { nxt_string("''.trim()"), + nxt_string("") }, + + { nxt_string("' '.trim()"), + nxt_string("") }, + + { nxt_string("'abc '.trim()"), + nxt_string("abc") }, + + { nxt_string("' abc'.trim()"), + nxt_string("abc") }, + + { nxt_string("' abc '.trim()"), + nxt_string("abc") }, + + { nxt_string("'??? '.trim()"), + nxt_string("???") }, + + { nxt_string("' ???'.trim()"), + nxt_string("???") }, + + { nxt_string("' ??? '.trim()"), + nxt_string("???") }, + + { nxt_string("'\\u2029abc\\uFEFF\\u2028'.trim()"), + nxt_string("abc") }, + { nxt_string("'abcdefgh'.search()"), nxt_string("0") }, From vbart at nginx.com Fri Oct 28 11:44:02 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 28 Oct 2016 11:44:02 +0000 Subject: [njs] String.prototype.repeat() method. Message-ID: details: http://hg.nginx.org/njs/rev/2cc08001fc78 branches: changeset: 227:2cc08001fc78 user: Valentin Bartenev date: Fri Oct 28 14:20:23 2016 +0300 description: String.prototype.repeat() method. diffstat: njs/njs_string.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 18 +++++++++++++++ 2 files changed, 73 insertions(+), 0 deletions(-) diffs (100 lines): diff -r 5de122a4031a -r 2cc08001fc78 njs/njs_string.c --- a/njs/njs_string.c Fri Oct 28 13:32:33 2016 +0300 +++ b/njs/njs_string.c Fri Oct 28 14:20:23 2016 +0300 @@ -1743,6 +1743,53 @@ done: } +static njs_ret_t +njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + u_char *p, *start; + int32_t n, max; + uint32_t size, length; + njs_string_prop_t string; + + n = 0; + + (void) njs_string_prop(&string, &args[0]); + + 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; + + start = njs_string_alloc(vm, &vm->retval, size, length); + if (nxt_slow_path(start == NULL)) { + return NXT_ERROR; + } + + p = start; + + while (n != 0) { + p = memcpy(p, string.start, string.size); + p += string.size; + n--; + } + + if (length >= NJS_STRING_MAP_OFFSET && size != length) { + njs_string_offset_map_init(start, size); + } + + return NXT_OK; +} + + /* * String.search([regexp]) */ @@ -3042,6 +3089,14 @@ static const njs_object_prop_t njs_stri NJS_STRING_OBJECT_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("repeat"), + .value = njs_native_function(njs_string_prototype_repeat, 0, + NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("search"), diff -r 5de122a4031a -r 2cc08001fc78 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Oct 28 13:32:33 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Oct 28 14:20:23 2016 +0300 @@ -3611,6 +3611,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("'0123456789'.split('').reverse().join('')"), nxt_string("9876543210") }, + { nxt_string("'abc'.repeat(3)"), + nxt_string("abcabcabc") }, + + { nxt_string("'???'.repeat(3)"), + nxt_string("?????????") }, + + { nxt_string("'abc'.repeat(0)"), + nxt_string("") }, + + { nxt_string("'abc'.repeat(NaN)"), + nxt_string("") }, + + { nxt_string("'abc'.repeat(Infinity)"), + nxt_string("RangeError") }, + + { nxt_string("'abc'.repeat(-1)"), + nxt_string("RangeError") }, + { nxt_string("encodeURI()"), nxt_string("undefined")}, From mdounin at mdounin.ru Fri Oct 28 12:49:41 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 28 Oct 2016 15:49:41 +0300 Subject: [PATCH] Event pipe: delete useless code. In-Reply-To: References: Message-ID: <20161028124941.GX73038@mdounin.ru> Hello! On Fri, Oct 28, 2016 at 04:41:49PM +0800, ?? (hucc) wrote: > It is useless code. There is no need to judge whether the first buf > is partially filled, just add the free buf after the head. Using the same buffer if it is possible to do so can be beneficial from performance point of view, as it will allow better memory caching. (Please avoid using HTML in posts here. Thank you.) -- Maxim Dounin http://nginx.org/ From dilaz03 at gmail.com Fri Oct 28 13:07:52 2016 From: dilaz03 at gmail.com (Dmitry Lazurkin) Date: Fri, 28 Oct 2016 16:07:52 +0300 Subject: [PATCH] [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: <20161026173232.GG73038@mdounin.ru> References: <41dc35ff-49c1-afde-81b6-a17d7bc0fda5@gmail.com> <9fbfc0ccb28e1eee624f.1477085476@user-notebook> <20161026173232.GG73038@mdounin.ru> Message-ID: <3a9f510d-96d0-9b60-7488-b13268b09a46@gmail.com> Hello, Maxim. Thank you! (: On 10/26/2016 08:32 PM, Maxim Dounin wrote: > Hello! > > On Sat, Oct 22, 2016 at 12:31:16AM +0300, dilaz03 at gmail.com wrote: > >> # HG changeset patch >> # User Dmitry Lazurkin >> # Date 1476631441 -10800 >> # Sun Oct 16 18:24:01 2016 +0300 >> # Node ID 9fbfc0ccb28e1eee624ff212de88fa1c051f09d9 >> # Parent 56d6bfe6b609c565a9f500bde573fd9b488ff960 >> Proxy: support variables for proxy_method directive. >> >> diff -r 56d6bfe6b609 -r 9fbfc0ccb28e src/http/modules/ngx_http_proxy_module.c >> --- a/src/http/modules/ngx_http_proxy_module.c Fri Oct 21 16:28:39 2016 +0300 >> +++ b/src/http/modules/ngx_http_proxy_module.c Sun Oct 16 18:24:01 2016 +0300 >> @@ -73,7 +73,7 @@ >> ngx_array_t *cookie_domains; >> ngx_array_t *cookie_paths; >> >> - ngx_str_t method; >> + ngx_http_complex_value_t *method; >> ngx_str_t location; >> ngx_str_t url; >> >> @@ -380,7 +380,7 @@ >> >> { ngx_string("proxy_method"), >> NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, >> - ngx_conf_set_str_slot, >> + ngx_http_set_complex_value_slot, >> NGX_HTTP_LOC_CONF_OFFSET, >> offsetof(ngx_http_proxy_loc_conf_t, method), >> NULL }, >> @@ -1159,8 +1159,10 @@ >> /* HEAD was changed to GET to cache response */ >> method = u->method; >> >> - } else if (plcf->method.len) { >> - method = plcf->method; >> + } else if (plcf->method != NULL) { >> + if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) { >> + return NGX_ERROR; >> + } >> >> } else { >> method = r->method_name; >> @@ -3158,7 +3160,9 @@ >> >> #endif >> >> - ngx_conf_merge_str_value(conf->method, prev->method, ""); >> + if (conf->method == NULL) { >> + conf->method = prev->method; >> + } >> >> ngx_conf_merge_value(conf->upstream.pass_request_headers, >> prev->upstream.pass_request_headers, 1); > Looks good, except a few style nits: > > - We don't usually check pointers with "!= NULL", just testing > "if (plcf->method)" would be enough here. > > - You've forgot to update the "set by ngx_pcalloc()" comment in > ngx_http_proxy_create_loc_conf(). > > Committed with the following patch on top: > > --- a/src/http/modules/ngx_http_proxy_module.c > +++ b/src/http/modules/ngx_http_proxy_module.c > @@ -1159,7 +1159,7 @@ ngx_http_proxy_create_request(ngx_http_r > /* HEAD was changed to GET to cache response */ > method = u->method; > > - } else if (plcf->method != NULL) { > + } else if (plcf->method) { > if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) { > return NGX_ERROR; > } > @@ -2799,7 +2799,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ > * conf->upstream.store_values = NULL; > * conf->upstream.ssl_name = NULL; > * > - * conf->method = { 0, NULL }; > + * conf->method = NULL; > * conf->headers_source = NULL; > * conf->headers.lengths = NULL; > * conf->headers.values = NULL; > > Thanks! > From dilaz03 at gmail.com Fri Oct 28 13:16:53 2016 From: dilaz03 at gmail.com (Dmitry Lazurkin) Date: Fri, 28 Oct 2016 16:16:53 +0300 Subject: [PATCH] Proxy: support variables for proxy_method directive In-Reply-To: <20161026173804.GH73038@mdounin.ru> References: <6f0d1849-460d-e2a7-1d1e-b96143e5f9f1@gmail.com> <20161026173804.GH73038@mdounin.ru> Message-ID: Hello, Maxim. On 10/26/2016 08:38 PM, Maxim Dounin wrote: > Such a test will fail on versions without variables support in > proxy_method. This is a problem, as the same test suite is used > to test both mainline and stable. To address this we use > conditional TODO tests with version checked: > > diff --git a/proxy_method.t b/proxy_method.t > --- a/proxy_method.t > +++ b/proxy_method.t > @@ -77,9 +77,14 @@ like(http_get('/preserve'), qr/request_m > like(http_get('/const'), qr/request_method=POST/, > 'proxy_method from constant'); > > +TODO: { > +local $TODO = 'not yet' unless $t->has_version('1.11.6'); > + > like(http_get('/var?method=POST'), qr/request_method=POST/, > 'proxy_method from variable'); > > +} > + > like(http_get('/parent/child'), qr/request_method=POST/, > 'proxy_method from parent'); > > Additionally, style is slighly different in our test scripts for > historical reasons, tabs are used to indent perl code. > > Committed with the above changes, thanks. > Sorry for indentation with spaces. I will be more careful. Thanks. From igor at sysoev.ru Fri Oct 28 20:14:51 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 28 Oct 2016 20:14:51 +0000 Subject: [njs] Added missing includes. Message-ID: details: http://hg.nginx.org/njs/rev/9b37882ad552 branches: changeset: 228:9b37882ad552 user: Piotr Sikora date: Fri Oct 28 19:29:38 2016 +0300 description: Added missing includes. Previously, most objects were compiled without any features detected by the ./configure script. Signed-off-by: Piotr Sikora diffstat: nginx/ngx_http_js_module.c | 1 + nginx/ngx_stream_js_module.c | 1 + njs/njs_array.c | 1 + njs/njs_boolean.c | 1 + njs/njs_builtin.c | 1 + njs/njs_disassembler.c | 1 + njs/njs_extern.c | 1 + njs/njs_function.c | 1 + njs/njs_generator.c | 1 + njs/njs_lexer.c | 1 + njs/njs_lexer_keyword.c | 1 + njs/njs_math.c | 1 + njs/njs_number.c | 1 + njs/njs_object.c | 1 + njs/njs_parser.c | 1 + njs/njs_variable.c | 1 + njs/njs_vm.c | 1 + njs/njscript.c | 1 + njs/test/njs_unit_test.c | 1 + nxt/nxt_array.c | 1 + nxt/nxt_djb_hash.c | 1 + nxt/nxt_lvlhsh.c | 1 + nxt/nxt_mem_cache_pool.c | 1 + nxt/nxt_murmur_hash.c | 1 + nxt/nxt_pcre.c | 1 + nxt/nxt_queue.c | 1 + nxt/nxt_random.c | 1 + nxt/nxt_rbtree.c | 1 + nxt/nxt_utf8.c | 1 + nxt/test/lvlhsh_unit_test.c | 1 + nxt/test/random_unit_test.c | 1 + nxt/test/rbtree_unit_test.c | 1 + nxt/test/utf8_unit_test.c | 1 + 33 files changed, 33 insertions(+), 0 deletions(-) diffs (363 lines): diff -r 2cc08001fc78 -r 9b37882ad552 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nginx/ngx_http_js_module.c Fri Oct 28 19:29:38 2016 +0300 @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nginx/ngx_stream_js_module.c Fri Oct 28 19:29:38 2016 +0300 @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_array.c --- a/njs/njs_array.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_array.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_boolean.c --- a/njs/njs_boolean.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_boolean.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_builtin.c --- a/njs/njs_builtin.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_builtin.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_disassembler.c --- a/njs/njs_disassembler.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_disassembler.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_extern.c --- a/njs/njs_extern.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_extern.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_function.c --- a/njs/njs_function.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_function.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_generator.c --- a/njs/njs_generator.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_generator.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_lexer.c --- a/njs/njs_lexer.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_lexer.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_lexer_keyword.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_math.c --- a/njs/njs_math.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_math.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_number.c --- a/njs/njs_number.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_number.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_object.c --- a/njs/njs_object.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_object.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_parser.c --- a/njs/njs_parser.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_parser.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_variable.c --- a/njs/njs_variable.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_variable.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njs_vm.c --- a/njs/njs_vm.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njs_vm.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/njscript.c --- a/njs/njscript.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/njscript.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Oct 28 14:20:23 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_array.c --- a/nxt/nxt_array.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_array.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_djb_hash.c --- a/nxt/nxt_djb_hash.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_djb_hash.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_lvlhsh.c --- a/nxt/nxt_lvlhsh.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_lvlhsh.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_mem_cache_pool.c --- a/nxt/nxt_mem_cache_pool.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_mem_cache_pool.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_murmur_hash.c --- a/nxt/nxt_murmur_hash.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_murmur_hash.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * released to the public domain. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_pcre.c --- a/nxt/nxt_pcre.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_pcre.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_queue.c --- a/nxt/nxt_queue.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_queue.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_random.c --- a/nxt/nxt_random.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_random.c Fri Oct 28 19:29:38 2016 +0300 @@ -5,6 +5,7 @@ */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_rbtree.c --- a/nxt/nxt_rbtree.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_rbtree.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/nxt_utf8.c --- a/nxt/nxt_utf8.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/nxt_utf8.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/test/lvlhsh_unit_test.c --- a/nxt/test/lvlhsh_unit_test.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/test/lvlhsh_unit_test.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/test/random_unit_test.c --- a/nxt/test/random_unit_test.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/test/random_unit_test.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/test/rbtree_unit_test.c --- a/nxt/test/rbtree_unit_test.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/test/rbtree_unit_test.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include diff -r 2cc08001fc78 -r 9b37882ad552 nxt/test/utf8_unit_test.c --- a/nxt/test/utf8_unit_test.c Fri Oct 28 14:20:23 2016 +0300 +++ b/nxt/test/utf8_unit_test.c Fri Oct 28 19:29:38 2016 +0300 @@ -4,6 +4,7 @@ * Copyright (C) NGINX, Inc. */ +#include #include #include #include From igor at sysoev.ru Fri Oct 28 21:05:47 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 28 Oct 2016 21:05:47 +0000 Subject: [njs] Fixed building on modern Linux kernels. Message-ID: details: http://hg.nginx.org/njs/rev/a1cd4104df67 branches: changeset: 229:a1cd4104df67 user: Igor Sysoev date: Sat Oct 29 00:04:29 2016 +0300 description: Fixed building on modern Linux kernels. diffstat: nxt/nxt_random.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 9b37882ad552 -r a1cd4104df67 nxt/nxt_random.c --- a/nxt/nxt_random.c Fri Oct 28 19:29:38 2016 +0300 +++ b/nxt/nxt_random.c Sat Oct 29 00:04:29 2016 +0300 @@ -70,7 +70,7 @@ nxt_random_stir(nxt_random_t *r, nxt_pid /* Linux 3.17 getrandom(), it is not available in Glibc. */ - n = syscall(SYS_getrandom, key, NXT_RANDOM_KEY_SIZE, 0)); + n = syscall(SYS_getrandom, key, NXT_RANDOM_KEY_SIZE, 0); #endif From igor at sysoev.ru Mon Oct 31 13:10:17 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 31 Oct 2016 13:10:17 +0000 Subject: [njs] A possible memory leak has been fixed. Message-ID: details: http://hg.nginx.org/njs/rev/f0ac27f59e58 branches: changeset: 230:f0ac27f59e58 user: Igor Sysoev date: Mon Oct 31 15:51:12 2016 +0300 description: A possible memory leak has been fixed. Thanks to ??? (Hong Zhi Dao). diffstat: nxt/nxt_mem_cache_pool.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (19 lines): diff -r a1cd4104df67 -r f0ac27f59e58 nxt/nxt_mem_cache_pool.c --- a/nxt/nxt_mem_cache_pool.c Sat Oct 29 00:04:29 2016 +0300 +++ b/nxt/nxt_mem_cache_pool.c Mon Oct 31 15:51:12 2016 +0300 @@ -574,14 +574,13 @@ nxt_mem_cache_alloc_large(nxt_mem_cache_ } else { block = pool->proto->alloc(pool->mem, sizeof(nxt_mem_cache_block_t)); - if (nxt_slow_path(block == NULL)) { - pool->proto->free(pool->mem, block); return NULL; } p = pool->proto->align(pool->mem, alignment, size); if (nxt_slow_path(p == NULL)) { + pool->proto->free(pool->mem, block); return NULL; } From igor at sysoev.ru Mon Oct 31 13:10:18 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 31 Oct 2016 13:10:18 +0000 Subject: [njs] A surplus check has been removed. Message-ID: details: http://hg.nginx.org/njs/rev/b0b46036d54e branches: changeset: 231:b0b46036d54e user: Igor Sysoev date: Mon Oct 31 15:56:49 2016 +0300 description: A surplus check has been removed. Found by Coverity Scan. diffstat: njs/njscript.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r f0ac27f59e58 -r b0b46036d54e njs/njscript.c --- a/njs/njscript.c Mon Oct 31 15:51:12 2016 +0300 +++ b/njs/njscript.c Mon Oct 31 15:56:49 2016 +0300 @@ -346,7 +346,7 @@ njs_vm_clone(njs_vm_t *vm, nxt_mem_cache fail: - if (mcp == NULL && nmcp != NULL) { + if (mcp == NULL) { nxt_mem_cache_pool_destroy(nmcp); } From vbart at nginx.com Mon Oct 31 13:29:20 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 31 Oct 2016 13:29:20 +0000 Subject: [njs] Math.trunc() method. Message-ID: details: http://hg.nginx.org/njs/rev/1f68ffabcea9 branches: changeset: 232:1f68ffabcea9 user: Valentin Bartenev date: Mon Oct 31 16:25:54 2016 +0300 description: Math.trunc() method. diffstat: njs/njs_math.c | 27 +++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 0 deletions(-) diffs (84 lines): diff -r b0b46036d54e -r 1f68ffabcea9 njs/njs_math.c --- a/njs/njs_math.c Mon Oct 31 15:56:49 2016 +0300 +++ b/njs/njs_math.c Mon Oct 31 16:25:54 2016 +0300 @@ -390,6 +390,25 @@ njs_object_math_tan(njs_vm_t *vm, njs_va } +static njs_ret_t +njs_object_math_trunc(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; + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, trunc(num)); + + return NXT_OK; +} + + static const njs_object_prop_t njs_math_object_properties[] = { { @@ -568,6 +587,14 @@ static const njs_object_prop_t njs_math .value = njs_native_function(njs_object_math_tan, 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 b0b46036d54e -r 1f68ffabcea9 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 31 15:56:49 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Oct 31 16:25:54 2016 +0300 @@ -5373,6 +5373,36 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.pow()"), nxt_string("NaN") }, + { nxt_string("Math.trunc(3.9)"), + nxt_string("3") }, + + { nxt_string("Math.trunc(-3.9)"), + nxt_string("-3") }, + + { nxt_string("Math.trunc(0)"), + nxt_string("0") }, + + { nxt_string("Math.trunc(-0)"), + nxt_string("-0") }, + + { nxt_string("Math.trunc(0.9)"), + nxt_string("0") }, + + { nxt_string("Math.trunc(-0.9)"), + nxt_string("-0") }, + + { nxt_string("Math.trunc(Infinity)"), + nxt_string("Infinity") }, + + { nxt_string("Math.trunc(-Infinity)"), + nxt_string("-Infinity") }, + + { nxt_string("Math.trunc(NaN)"), + nxt_string("NaN") }, + + { nxt_string("Math.trunc()"), + nxt_string("NaN") }, + /* ES5FIX: "[object Math]". */ { nxt_string("Math"), From vbart at nginx.com Mon Oct 31 13:29:22 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 31 Oct 2016 13:29:22 +0000 Subject: [njs] Math.sign() method. Message-ID: details: http://hg.nginx.org/njs/rev/d7a10c0dfcce branches: changeset: 233:d7a10c0dfcce user: Valentin Bartenev date: Mon Oct 31 16:28:12 2016 +0300 description: Math.sign() method. diffstat: njs/njs_math.c | 31 +++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 18 ++++++++++++++++++ 2 files changed, 49 insertions(+), 0 deletions(-) diffs (76 lines): diff -r 1f68ffabcea9 -r d7a10c0dfcce njs/njs_math.c --- a/njs/njs_math.c Mon Oct 31 16:25:54 2016 +0300 +++ b/njs/njs_math.c Mon Oct 31 16:28:12 2016 +0300 @@ -334,6 +334,29 @@ njs_object_math_round(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_sign(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 (!njs_is_nan(num) && num != 0) { + num = signbit(num) ? -1 : 1; + } + + } else { + num = NJS_NAN; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_sin(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -567,6 +590,14 @@ static const njs_object_prop_t njs_math NJS_SKIP_ARG, NJS_NUMBER_ARG), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("sign"), + .value = njs_native_function(njs_object_math_sign, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("sin"), diff -r 1f68ffabcea9 -r d7a10c0dfcce njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Oct 31 16:25:54 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Oct 31 16:28:12 2016 +0300 @@ -5373,6 +5373,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.pow()"), nxt_string("NaN") }, + { nxt_string("Math.sign(5)"), + nxt_string("1") }, + + { nxt_string("Math.sign(-5)"), + nxt_string("-1") }, + + { nxt_string("Math.sign(0)"), + nxt_string("0") }, + + { nxt_string("Math.sign(-0.0)"), + nxt_string("-0") }, + + { nxt_string("Math.sign(NaN)"), + nxt_string("NaN") }, + + { nxt_string("Math.sign()"), + nxt_string("NaN") }, + { nxt_string("Math.trunc(3.9)"), nxt_string("3") }, From vbart at nginx.com Mon Oct 31 13:33:13 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Mon, 31 Oct 2016 13:33:13 +0000 Subject: [nginx] HTTP/2: limited maximum number of requests in connection. Message-ID: details: http://hg.nginx.org/nginx/rev/9027991e2f37 branches: changeset: 6783:9027991e2f37 user: Valentin Bartenev date: Mon Oct 31 16:33:02 2016 +0300 description: HTTP/2: limited maximum number of requests in connection. The new directive "http2_max_requests" is introduced. From users point of view it works quite similar to "keepalive_requests" but has significantly bigger default value that is more suitable for HTTP/2. diffstat: src/http/v2/ngx_http_v2.c | 34 ++++++++++++++++++++++++---------- src/http/v2/ngx_http_v2_module.c | 9 +++++++++ src/http/v2/ngx_http_v2_module.h | 1 + 3 files changed, 34 insertions(+), 10 deletions(-) diffs (95 lines): diff -r b123eae3fd4e -r 9027991e2f37 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Oct 27 17:57:16 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Mon Oct 31 16:33:02 2016 +0300 @@ -326,16 +326,21 @@ ngx_http_v2_read_handler(ngx_event_t *re if (c->close) { c->close = 0; - h2c->goaway = 1; - - if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) { - ngx_http_v2_finalize_connection(h2c, 0); - return; - } - - if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { - ngx_http_v2_finalize_connection(h2c, 0); - return; + + if (!h2c->goaway) { + h2c->goaway = 1; + + if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) + == NGX_ERROR) + { + ngx_http_v2_finalize_connection(h2c, 0); + return; + } + + if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { + ngx_http_v2_finalize_connection(h2c, 0); + return; + } } h2c->blocked = 0; @@ -1177,6 +1182,15 @@ ngx_http_v2_state_headers(ngx_http_v2_co ngx_http_v2_set_dependency(h2c, node, depend, excl); } + if (h2c->connection->requests >= h2scf->max_requests) { + h2c->goaway = 1; + + if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) { + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + } + return ngx_http_v2_state_header_block(h2c, pos, end); rst_stream: diff -r b123eae3fd4e -r 9027991e2f37 src/http/v2/ngx_http_v2_module.c --- a/src/http/v2/ngx_http_v2_module.c Thu Oct 27 17:57:16 2016 +0300 +++ b/src/http/v2/ngx_http_v2_module.c Mon Oct 31 16:33:02 2016 +0300 @@ -73,6 +73,13 @@ static ngx_command_t ngx_http_v2_comman offsetof(ngx_http_v2_srv_conf_t, concurrent_streams), NULL }, + { ngx_string("http2_max_requests"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_v2_srv_conf_t, max_requests), + NULL }, + { ngx_string("http2_max_field_size"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, @@ -322,6 +329,7 @@ ngx_http_v2_create_srv_conf(ngx_conf_t * h2scf->pool_size = NGX_CONF_UNSET_SIZE; h2scf->concurrent_streams = NGX_CONF_UNSET_UINT; + h2scf->max_requests = NGX_CONF_UNSET_UINT; h2scf->max_field_size = NGX_CONF_UNSET_SIZE; h2scf->max_header_size = NGX_CONF_UNSET_SIZE; @@ -347,6 +355,7 @@ ngx_http_v2_merge_srv_conf(ngx_conf_t *c ngx_conf_merge_uint_value(conf->concurrent_streams, prev->concurrent_streams, 128); + ngx_conf_merge_uint_value(conf->max_requests, prev->max_requests, 1000); ngx_conf_merge_size_value(conf->max_field_size, prev->max_field_size, 4096); diff -r b123eae3fd4e -r 9027991e2f37 src/http/v2/ngx_http_v2_module.h --- a/src/http/v2/ngx_http_v2_module.h Thu Oct 27 17:57:16 2016 +0300 +++ b/src/http/v2/ngx_http_v2_module.h Mon Oct 31 16:33:02 2016 +0300 @@ -23,6 +23,7 @@ typedef struct { typedef struct { size_t pool_size; ngx_uint_t concurrent_streams; + ngx_uint_t max_requests; size_t max_field_size; size_t max_header_size; size_t preread_size; From ru at nginx.com Mon Oct 31 20:39:49 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 31 Oct 2016 20:39:49 +0000 Subject: [nginx] Upstream: removed unnecessary condition in proxy_eval() and friends. Message-ID: details: http://hg.nginx.org/nginx/rev/1af120241cde branches: changeset: 6784:1af120241cde user: Ruslan Ermilov date: Mon Oct 31 18:33:31 2016 +0300 description: Upstream: removed unnecessary condition in proxy_eval() and friends. The first condition added in d3454e719bbb should have just replaced the second one. diffstat: src/http/modules/ngx_http_fastcgi_module.c | 2 +- src/http/modules/ngx_http_proxy_module.c | 2 +- src/http/modules/ngx_http_scgi_module.c | 2 +- src/http/modules/ngx_http_uwsgi_module.c | 2 +- src/stream/ngx_stream_proxy_module.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diffs (60 lines): diff -r 9027991e2f37 -r 1af120241cde src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Mon Oct 31 16:33:02 2016 +0300 +++ b/src/http/modules/ngx_http_fastcgi_module.c Mon Oct 31 18:33:31 2016 +0300 @@ -766,7 +766,7 @@ ngx_http_fastcgi_eval(ngx_http_request_t return NGX_ERROR; } - if (url.addrs && url.addrs[0].sockaddr) { + if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; diff -r 9027991e2f37 -r 1af120241cde src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Mon Oct 31 16:33:02 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Mon Oct 31 18:33:31 2016 +0300 @@ -1008,7 +1008,7 @@ ngx_http_proxy_eval(ngx_http_request_t * return NGX_ERROR; } - if (url.addrs && url.addrs[0].sockaddr) { + if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; diff -r 9027991e2f37 -r 1af120241cde src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c Mon Oct 31 16:33:02 2016 +0300 +++ b/src/http/modules/ngx_http_scgi_module.c Mon Oct 31 18:33:31 2016 +0300 @@ -562,7 +562,7 @@ ngx_http_scgi_eval(ngx_http_request_t *r return NGX_ERROR; } - if (url.addrs && url.addrs[0].sockaddr) { + if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; diff -r 9027991e2f37 -r 1af120241cde src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Mon Oct 31 16:33:02 2016 +0300 +++ b/src/http/modules/ngx_http_uwsgi_module.c Mon Oct 31 18:33:31 2016 +0300 @@ -764,7 +764,7 @@ ngx_http_uwsgi_eval(ngx_http_request_t * return NGX_ERROR; } - if (url.addrs && url.addrs[0].sockaddr) { + if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; diff -r 9027991e2f37 -r 1af120241cde src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Mon Oct 31 16:33:02 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Mon Oct 31 18:33:31 2016 +0300 @@ -578,7 +578,7 @@ ngx_stream_proxy_eval(ngx_stream_session return NGX_ERROR; } - if (url.addrs && url.addrs[0].sockaddr) { + if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; From ru at nginx.com Mon Oct 31 20:39:51 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 31 Oct 2016 20:39:51 +0000 Subject: [nginx] Upstream: added the ngx_http_upstream_resolved_t.name field. Message-ID: details: http://hg.nginx.org/nginx/rev/d1d0dd69a419 branches: changeset: 6785:d1d0dd69a419 user: Ruslan Ermilov date: Mon Oct 31 18:33:33 2016 +0300 description: Upstream: added the ngx_http_upstream_resolved_t.name field. This fixes inconsistency in what is stored in the "host" field. Normally it would contain the "host" part of the parsed URL (e.g., proxy_pass with variables), but for the case of an implicit upstream specified with literal address it contained the text representation of the socket address (that is, host including port for IP). Now the "host" field always contains the "host" part of the URL, while the text representation of the socket address is stored in the newly added "name" field. The ngx_http_upstream_create_round_robin_peer() function was modified accordingly in a way to be compatible with the code that does not know about the new "name" field. The "stream" code was similarly modified except for not adding compatibility in ngx_stream_upstream_create_round_robin_peer(). This change is also a prerequisite for the next change. diffstat: src/http/modules/ngx_http_fastcgi_module.c | 6 ++---- src/http/modules/ngx_http_proxy_module.c | 6 ++---- src/http/modules/ngx_http_scgi_module.c | 6 ++---- src/http/modules/ngx_http_uwsgi_module.c | 6 ++---- src/http/ngx_http_upstream.h | 1 + src/http/ngx_http_upstream_round_robin.c | 2 +- src/stream/ngx_stream_proxy_module.c | 6 ++---- src/stream/ngx_stream_upstream.h | 1 + src/stream/ngx_stream_upstream_round_robin.c | 2 +- 9 files changed, 14 insertions(+), 22 deletions(-) diffs (141 lines): diff -r 1af120241cde -r d1d0dd69a419 src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Mon Oct 31 18:33:31 2016 +0300 +++ b/src/http/modules/ngx_http_fastcgi_module.c Mon Oct 31 18:33:33 2016 +0300 @@ -769,13 +769,11 @@ ngx_http_fastcgi_eval(ngx_http_request_t if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; + u->resolved->name = url.addrs[0].name; u->resolved->naddrs = 1; - u->resolved->host = url.addrs[0].name; - - } else { - u->resolved->host = url.host; } + u->resolved->host = url.host; u->resolved->port = url.port; u->resolved->no_port = url.no_port; diff -r 1af120241cde -r d1d0dd69a419 src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Mon Oct 31 18:33:31 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Mon Oct 31 18:33:33 2016 +0300 @@ -1011,13 +1011,11 @@ ngx_http_proxy_eval(ngx_http_request_t * if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; + u->resolved->name = url.addrs[0].name; u->resolved->naddrs = 1; - u->resolved->host = url.addrs[0].name; - - } else { - u->resolved->host = url.host; } + u->resolved->host = url.host; u->resolved->port = (in_port_t) (url.no_port ? port : url.port); u->resolved->no_port = url.no_port; diff -r 1af120241cde -r d1d0dd69a419 src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c Mon Oct 31 18:33:31 2016 +0300 +++ b/src/http/modules/ngx_http_scgi_module.c Mon Oct 31 18:33:33 2016 +0300 @@ -565,13 +565,11 @@ ngx_http_scgi_eval(ngx_http_request_t *r if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; + u->resolved->name = url.addrs[0].name; u->resolved->naddrs = 1; - u->resolved->host = url.addrs[0].name; - - } else { - u->resolved->host = url.host; } + u->resolved->host = url.host; u->resolved->port = url.port; u->resolved->no_port = url.no_port; diff -r 1af120241cde -r d1d0dd69a419 src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Mon Oct 31 18:33:31 2016 +0300 +++ b/src/http/modules/ngx_http_uwsgi_module.c Mon Oct 31 18:33:33 2016 +0300 @@ -767,13 +767,11 @@ ngx_http_uwsgi_eval(ngx_http_request_t * if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; + u->resolved->name = url.addrs[0].name; u->resolved->naddrs = 1; - u->resolved->host = url.addrs[0].name; - - } else { - u->resolved->host = url.host; } + u->resolved->host = url.host; u->resolved->port = url.port; u->resolved->no_port = url.no_port; diff -r 1af120241cde -r d1d0dd69a419 src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Mon Oct 31 18:33:31 2016 +0300 +++ b/src/http/ngx_http_upstream.h Mon Oct 31 18:33:33 2016 +0300 @@ -300,6 +300,7 @@ typedef struct { struct sockaddr *sockaddr; socklen_t socklen; + ngx_str_t name; ngx_resolver_ctx_t *ctx; } ngx_http_upstream_resolved_t; diff -r 1af120241cde -r d1d0dd69a419 src/http/ngx_http_upstream_round_robin.c --- a/src/http/ngx_http_upstream_round_robin.c Mon Oct 31 18:33:31 2016 +0300 +++ b/src/http/ngx_http_upstream_round_robin.c Mon Oct 31 18:33:33 2016 +0300 @@ -337,7 +337,7 @@ ngx_http_upstream_create_round_robin_pee if (ur->sockaddr) { peer[0].sockaddr = ur->sockaddr; peer[0].socklen = ur->socklen; - peer[0].name = ur->host; + peer[0].name = ur->name.data ? ur->name : ur->host; peer[0].weight = 1; peer[0].effective_weight = 1; peer[0].current_weight = 0; diff -r 1af120241cde -r d1d0dd69a419 src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Mon Oct 31 18:33:31 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Mon Oct 31 18:33:33 2016 +0300 @@ -581,13 +581,11 @@ ngx_stream_proxy_eval(ngx_stream_session if (url.addrs) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; + u->resolved->name = url.addrs[0].name; u->resolved->naddrs = 1; - u->resolved->host = url.addrs[0].name; - - } else { - u->resolved->host = url.host; } + u->resolved->host = url.host; u->resolved->port = url.port; u->resolved->no_port = url.no_port; diff -r 1af120241cde -r d1d0dd69a419 src/stream/ngx_stream_upstream.h --- a/src/stream/ngx_stream_upstream.h Mon Oct 31 18:33:31 2016 +0300 +++ b/src/stream/ngx_stream_upstream.h Mon Oct 31 18:33:33 2016 +0300 @@ -105,6 +105,7 @@ typedef struct { struct sockaddr *sockaddr; socklen_t socklen; + ngx_str_t name; ngx_resolver_ctx_t *ctx; } ngx_stream_upstream_resolved_t; diff -r 1af120241cde -r d1d0dd69a419 src/stream/ngx_stream_upstream_round_robin.c --- a/src/stream/ngx_stream_upstream_round_robin.c Mon Oct 31 18:33:31 2016 +0300 +++ b/src/stream/ngx_stream_upstream_round_robin.c Mon Oct 31 18:33:33 2016 +0300 @@ -344,7 +344,7 @@ ngx_stream_upstream_create_round_robin_p if (ur->sockaddr) { peer[0].sockaddr = ur->sockaddr; peer[0].socklen = ur->socklen; - peer[0].name = ur->host; + peer[0].name = ur->name; peer[0].weight = 1; peer[0].effective_weight = 1; peer[0].current_weight = 0; From ru at nginx.com Mon Oct 31 20:39:54 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 31 Oct 2016 20:39:54 +0000 Subject: [nginx] Upstream: do not unnecessarily create per-request upstreams. Message-ID: details: http://hg.nginx.org/nginx/rev/906ac20234ed branches: changeset: 6786:906ac20234ed user: Ruslan Ermilov date: Mon Oct 31 18:33:36 2016 +0300 description: Upstream: do not unnecessarily create per-request upstreams. If proxy_pass (and friends) with variables evaluates an upstream specified with literal address, nginx always created a per-request upstream. Now, if there's a matching upstream specified in the configuration (either implicit or explicit), it will be used instead. diffstat: src/http/ngx_http_upstream.c | 34 +++++++++++++++++----------------- src/stream/ngx_stream_proxy_module.c | 34 +++++++++++++++++----------------- 2 files changed, 34 insertions(+), 34 deletions(-) diffs (102 lines): diff -r d1d0dd69a419 -r 906ac20234ed src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Oct 31 18:33:33 2016 +0300 +++ b/src/http/ngx_http_upstream.c Mon Oct 31 18:33:36 2016 +0300 @@ -654,6 +654,23 @@ ngx_http_upstream_init_request(ngx_http_ host = &u->resolved->host; + umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); + + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + + uscf = uscfp[i]; + + if (uscf->host.len == host->len + && ((uscf->port == 0 && u->resolved->no_port) + || uscf->port == u->resolved->port) + && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0) + { + goto found; + } + } + if (u->resolved->sockaddr) { if (u->resolved->port == 0 @@ -679,23 +696,6 @@ ngx_http_upstream_init_request(ngx_http_ return; } - umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); - - uscfp = umcf->upstreams.elts; - - for (i = 0; i < umcf->upstreams.nelts; i++) { - - uscf = uscfp[i]; - - if (uscf->host.len == host->len - && ((uscf->port == 0 && u->resolved->no_port) - || uscf->port == u->resolved->port) - && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0) - { - goto found; - } - } - if (u->resolved->port == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no port in upstream \"%V\"", host); diff -r d1d0dd69a419 -r 906ac20234ed src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Mon Oct 31 18:33:33 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Mon Oct 31 18:33:36 2016 +0300 @@ -433,6 +433,23 @@ ngx_stream_proxy_handler(ngx_stream_sess host = &u->resolved->host; + umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module); + + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + + uscf = uscfp[i]; + + if (uscf->host.len == host->len + && ((uscf->port == 0 && u->resolved->no_port) + || uscf->port == u->resolved->port) + && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0) + { + goto found; + } + } + if (u->resolved->sockaddr) { if (u->resolved->port == 0 @@ -456,23 +473,6 @@ ngx_stream_proxy_handler(ngx_stream_sess return; } - umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module); - - uscfp = umcf->upstreams.elts; - - for (i = 0; i < umcf->upstreams.nelts; i++) { - - uscf = uscfp[i]; - - if (uscf->host.len == host->len - && ((uscf->port == 0 && u->resolved->no_port) - || uscf->port == u->resolved->port) - && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0) - { - goto found; - } - } - if (u->resolved->port == 0) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "no port in upstream \"%V\"", host); From ru at nginx.com Mon Oct 31 20:39:56 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 31 Oct 2016 20:39:56 +0000 Subject: [nginx] Upstream: consistently initialize explicit upstreams. Message-ID: details: http://hg.nginx.org/nginx/rev/640e1e778de6 branches: changeset: 6787:640e1e778de6 user: Ruslan Ermilov date: Mon Oct 17 14:14:02 2016 +0300 description: Upstream: consistently initialize explicit upstreams. When an upstream{} block follows a proxy_pass reference to it, such an upstream inherited port and default_port settings from proxy_pass. This was different from when they came in another order (see ticket #1059). Explicit upstreams should not have port and default_port in any case. This fixes the following case: server { location / { proxy_pass http://u; } ... } upstream u { server 127.0.0.1; } server { location / { proxy_pass https://u; } ... } but not the following: server { location / { proxy_pass http://u; } ... } server { location / { proxy_pass https://u; } ... } upstream u { server 127.0.0.1; } diffstat: src/http/ngx_http_upstream.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 906ac20234ed -r 640e1e778de6 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Oct 31 18:33:36 2016 +0300 +++ b/src/http/ngx_http_upstream.c Mon Oct 17 14:14:02 2016 +0300 @@ -5768,6 +5768,8 @@ ngx_http_upstream_add(ngx_conf_t *cf, ng if (flags & NGX_HTTP_UPSTREAM_CREATE) { uscfp[i]->flags = flags; + uscfp[i]->port = 0; + uscfp[i]->default_port = 0; } return uscfp[i]; From ru at nginx.com Mon Oct 31 20:40:02 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 31 Oct 2016 20:40:02 +0000 Subject: [nginx] Upstream: removed ngx_http_upstream_srv_conf_t.default_port. Message-ID: details: http://hg.nginx.org/nginx/rev/4dea01cf49e8 branches: changeset: 6789:4dea01cf49e8 user: Ruslan Ermilov date: Mon Oct 17 14:30:54 2016 +0300 description: Upstream: removed ngx_http_upstream_srv_conf_t.default_port. This is an API change. diffstat: src/http/ngx_http_upstream.c | 2 -- src/http/ngx_http_upstream.h | 1 - 2 files changed, 0 insertions(+), 3 deletions(-) diffs (30 lines): diff -r 3fa5983b6b44 -r 4dea01cf49e8 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Oct 17 14:27:45 2016 +0300 +++ b/src/http/ngx_http_upstream.c Mon Oct 17 14:30:54 2016 +0300 @@ -5763,7 +5763,6 @@ ngx_http_upstream_add(ngx_conf_t *cf, ng if (flags & NGX_HTTP_UPSTREAM_CREATE) { uscfp[i]->flags = flags; uscfp[i]->port = 0; - uscfp[i]->default_port = 0; } return uscfp[i]; @@ -5779,7 +5778,6 @@ ngx_http_upstream_add(ngx_conf_t *cf, ng uscf->file_name = cf->conf_file->file.name.data; uscf->line = cf->conf_file->line; uscf->port = u->port; - uscf->default_port = u->default_port; uscf->no_port = u->no_port; if (u->naddrs == 1 && (u->port || u->family == AF_UNIX)) { diff -r 3fa5983b6b44 -r 4dea01cf49e8 src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Mon Oct 17 14:27:45 2016 +0300 +++ b/src/http/ngx_http_upstream.h Mon Oct 17 14:30:54 2016 +0300 @@ -128,7 +128,6 @@ struct ngx_http_upstream_srv_conf_s { u_char *file_name; ngx_uint_t line; in_port_t port; - in_port_t default_port; ngx_uint_t no_port; /* unsigned no_port:1 */ #if (NGX_HTTP_UPSTREAM_ZONE) From ru at nginx.com Mon Oct 31 20:40:05 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 31 Oct 2016 20:40:05 +0000 Subject: [nginx] HTTP/2: slightly improved debugging. Message-ID: details: http://hg.nginx.org/nginx/rev/727c6412673a branches: changeset: 6790:727c6412673a user: Ruslan Ermilov date: Mon Oct 31 23:38:51 2016 +0300 description: HTTP/2: slightly improved debugging. diffstat: src/http/v2/ngx_http_v2.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diffs (24 lines): diff -r 4dea01cf49e8 -r 727c6412673a src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Mon Oct 17 14:30:54 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Mon Oct 31 23:38:51 2016 +0300 @@ -2592,7 +2592,7 @@ ngx_http_v2_send_rst_stream(ngx_http_v2_ ngx_http_v2_out_frame_t *frame; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 send RST_STREAM frame sid:%ui, status:%uz", + "http2 send RST_STREAM frame sid:%ui, status:%ui", sid, status); frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_RST_STREAM_SIZE, @@ -2618,8 +2618,9 @@ ngx_http_v2_send_goaway(ngx_http_v2_conn ngx_buf_t *buf; ngx_http_v2_out_frame_t *frame; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 send GOAWAY frame, status:%uz", status); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 send GOAWAY frame: last sid %ui, error %ui", + h2c->last_sid, status); frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_GOAWAY_SIZE, NGX_HTTP_V2_GOAWAY_FRAME, From ru at nginx.com Mon Oct 31 20:39:59 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 31 Oct 2016 20:39:59 +0000 Subject: [nginx] Upstream: don't consider default_port when matching upstreams. Message-ID: details: http://hg.nginx.org/nginx/rev/3fa5983b6b44 branches: changeset: 6788:3fa5983b6b44 user: Ruslan Ermilov date: Mon Oct 17 14:27:45 2016 +0300 description: Upstream: don't consider default_port when matching upstreams. The only thing that default_port comparison did in the current code is prevented implicit upstreams to the same address/port from being aliased for http and https, e.g.: proxy_pass http://10.0.0.1:12345; proxy_pass https://10.0.0.1:12345; This is inconsistent because it doesn't work for a similar case with uswgi_pass: uwsgi_pass uwsgi://10.0.0.1:12345; uwsgi_pass suwsgi://10.0.0.1:12345; or with an explicit upstream: upstream u { server 10.0.0.1:12345; } proxy_pass http://u; proxy_pass https://u; Before c9059bd5445b, default_port comparison was needed to differentiate implicit upstreams in proxy_pass http://example.com; and proxy_pass https://example.com; as u->port was not set. diffstat: src/http/ngx_http_upstream.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-) diffs (16 lines): diff -r 640e1e778de6 -r 3fa5983b6b44 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Oct 17 14:14:02 2016 +0300 +++ b/src/http/ngx_http_upstream.c Mon Oct 17 14:27:45 2016 +0300 @@ -5760,12 +5760,6 @@ ngx_http_upstream_add(ngx_conf_t *cf, ng continue; } - if (uscfp[i]->default_port && u->default_port - && uscfp[i]->default_port != u->default_port) - { - continue; - } - if (flags & NGX_HTTP_UPSTREAM_CREATE) { uscfp[i]->flags = flags; uscfp[i]->port = 0;