Re: [PATCH 1 of 6] SSL: define NGX_SSL_VERIFY constants

2016-10-18 Thread Piotr Sikora
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

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


Re: [PATCH 1 of 6] SSL: define NGX_SSL_VERIFY constants

2016-10-18 Thread Maxim Dounin
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/

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


Re: [PATCH 2 of 6] SSL: pull common SSL defines into OpenSSL module

2016-10-18 Thread Piotr Sikora
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

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


Re: [PATCH 1 of 6] SSL: define NGX_SSL_VERIFY constants

2016-10-18 Thread Piotr Sikora
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

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


Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-18 Thread Maxim Dounin
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@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

[nginx] SSL: overcame possible buffer over-read in ngx_ssl_error().

2016-10-18 Thread Valentin Bartenev
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;
 }
 

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


[nginx] Mail: extensible auth methods in pop3 module.

2016-10-18 Thread Maxim Dounin
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, 

[nginx] Mail: support SASL EXTERNAL (RFC 4422).

2016-10-18 Thread Maxim Dounin
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_USERNAME2
 #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\"", [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(, [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\"", >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
+++ 

[nginx] release-1.10.2 tag

2016-10-18 Thread Maxim Dounin
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

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


[nginx] nginx-1.10.2-RELEASE

2016-10-18 Thread Maxim Dounin
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.
+
+
+
+
+
+
 
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

[njs] Array.indexOf() and Array.lastIndexOf() have been fixed.

2016-10-18 Thread Igor Sysoev
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([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") },
 

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


[nginx] Updated OpenSSL used for win32 builds.

2016-10-18 Thread Maxim Dounin
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
 

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


[nginx] SSL: guarded SSL_R_NO_CIPHERS_PASSED not present in OpenSSL 1.1.0.

2016-10-18 Thread Maxim Dounin
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 */

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


[nginx] SSL: adopted session ticket handling for OpenSSL 1.1.0.

2016-10-18 Thread Maxim Dounin
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 */

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


[nginx] Event pipe: do not set file's thread_handler if not needed.

2016-10-18 Thread Maxim Dounin
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);

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


[nginx] SSL: default DH parameters compatible with OpenSSL 1.1.0.

2016-10-18 Thread Maxim Dounin
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 < 0x1015L
+
 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);

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


[nginx] HTTP/2: flushing of the SSL buffer in transition to the idle state.

2016-10-18 Thread Maxim Dounin
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_trc;
+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,

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


[nginx] HTTP/2: refactored ngx_http_v2_send_output_queue().

2016-10-18 Thread Maxim Dounin
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:

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


[nginx] HTTP/2: prevented output of the HEADERS frame for canceled streams.

2016-10-18 Thread Maxim Dounin
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] == '/') {

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


[nginx] HTTP/2: always handle streams in error state.

2016-10-18 Thread Maxim Dounin
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(>posted, >queue);
+if (!fc->error && (stream->exhausted || fc->write->delayed)) {
+return;
 }
+
+stream->handled = 1;
+ngx_queue_insert_tail(>posted, >queue);
 }
 
 

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


[nginx] Sub filter: eliminate unnecessary buffering.

2016-10-18 Thread Maxim Dounin
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\"", >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 = [i].match;
+
+if (ngx_http_sub_match(ctx, start, m) == NGX_AGAIN) {
+goto again;
+}
+}
+
+offset++;
+}
+}
+
 again:
 
 ctx->offset = offset;

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


[nginx] HTTP/2: fixed send timer handling.

2016-10-18 Thread Maxim Dounin
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 {

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


[nginx] HTTP/2: fixed the "http request count is zero" alert.

2016-10-18 Thread Maxim Dounin
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;
 }
 

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


[nginx] Sub filter: introduced the ngx_http_sub_match() function.

2016-10-18 Thread Maxim Dounin
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_tshift, i, j;
@@ -641,41 +643,15 @@ ngx_http_sub_parse(ngx_http_request_t *r
 
 m = [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)
 {

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


[nginx] HTTP/2: always send GOAWAY while worker is shutting down.

2016-10-18 Thread Maxim Dounin
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;
 }
 

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


[nginx] Updated PCRE used for win32 builds.

2016-10-18 Thread Maxim Dounin
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

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


[nginx] HTTP/2: prevented double termination of a stream.

2016-10-18 Thread Maxim Dounin
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;

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


[nginx] HTTP/2: avoid adding Content-Length for requests without body.

2016-10-18 Thread Maxim Dounin
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;
 }
 

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


[nginx] HTTP/2: fixed a segfault while processing unbuffered upload.

2016-10-18 Thread Maxim Dounin
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;

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


[nginx] HTTP/2: implemented preread buffer for request body (closes #959).

2016-10-18 Thread Maxim Dounin
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_trc;
+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 & 

[njs] Fixes in generating "continue" and "break" statements.

2016-10-18 Thread Igor Sysoev
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"),

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


[njs] A fix of function name usage.

2016-10-18 Thread Igor Sysoev
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.hTue Oct 18 15:48:13 2016 +0300
+++ b/njs/njs_variable.hTue 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;

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