From ru at nginx.com Tue Feb 2 08:35:35 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 02 Feb 2016 08:35:35 +0000 Subject: [nginx] Resolver: fixed possible resource leak introduced in 5a1... Message-ID: details: http://hg.nginx.org/nginx/rev/d73f77bb5caf branches: changeset: 6368:d73f77bb5caf user: Ruslan Ermilov date: Tue Feb 02 11:35:19 2016 +0300 description: Resolver: fixed possible resource leak introduced in 5a16d40c63de. Found by Coverity (CID 1351175). diffstat: src/core/ngx_resolver.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (19 lines): diff -r 5a16d40c63de -r d73f77bb5caf src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Thu Jan 28 15:28:20 2016 +0300 +++ b/src/core/ngx_resolver.c Tue Feb 02 11:35:19 2016 +0300 @@ -1215,6 +1215,7 @@ ngx_resolver_send_tcp_query(ngx_resolver b->start = ngx_resolver_alloc(r, NGX_RESOLVER_TCP_RSIZE); if (b->start == NULL) { + ngx_resolver_free(r, b); return NGX_ERROR; } @@ -1236,6 +1237,7 @@ ngx_resolver_send_tcp_query(ngx_resolver b->start = ngx_resolver_alloc(r, NGX_RESOLVER_TCP_WSIZE); if (b->start == NULL) { + ngx_resolver_free(r, b); return NGX_ERROR; } From arut at nginx.com Tue Feb 2 10:44:00 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 02 Feb 2016 10:44:00 +0000 Subject: [nginx] Resolver: free TCP buffers on resolver cleanup. Message-ID: details: http://hg.nginx.org/nginx/rev/06459bc8b92f branches: changeset: 6369:06459bc8b92f user: Roman Arutyunyan date: Tue Feb 02 13:42:55 2016 +0300 description: Resolver: free TCP buffers on resolver cleanup. diffstat: src/core/ngx_resolver.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diffs (20 lines): diff -r d73f77bb5caf -r 06459bc8b92f src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Tue Feb 02 11:35:19 2016 +0300 +++ b/src/core/ngx_resolver.c Tue Feb 02 13:42:55 2016 +0300 @@ -295,6 +295,16 @@ ngx_resolver_cleanup(void *data) if (rec[i].tcp) { ngx_close_connection(rec[i].tcp); } + + if (rec[i].read_buf) { + ngx_resolver_free(r, rec[i].read_buf->start); + ngx_resolver_free(r, rec[i].read_buf); + } + + if (rec[i].write_buf) { + ngx_resolver_free(r, rec[i].write_buf->start); + ngx_resolver_free(r, rec[i].write_buf); + } } ngx_free(r); From ru at nginx.com Tue Feb 2 10:48:04 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 02 Feb 2016 10:48:04 +0000 Subject: [nginx] Resolver: style. Message-ID: details: http://hg.nginx.org/nginx/rev/8c8739bdd3f1 branches: changeset: 6370:8c8739bdd3f1 user: Ruslan Ermilov date: Thu Dec 17 17:21:12 2015 +0300 description: Resolver: style. Renamed argument in ngx_resolver_process_a() for consistency. diffstat: src/core/ngx_resolver.c | 28 ++++++++++++++-------------- 1 files changed, 14 insertions(+), 14 deletions(-) diffs (110 lines): diff -r 06459bc8b92f -r 8c8739bdd3f1 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Tue Feb 02 13:42:55 2016 +0300 +++ b/src/core/ngx_resolver.c Thu Dec 17 17:21:12 2015 +0300 @@ -1738,7 +1738,7 @@ dns_error: static void -ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last, +ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n, ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype, ngx_uint_t nan, ngx_uint_t trunc, ngx_uint_t ans) { @@ -1750,7 +1750,7 @@ ngx_resolver_process_a(ngx_resolver_t *r in_addr_t *addr; ngx_str_t name; ngx_addr_t *addrs; - ngx_uint_t type, class, qident, naddrs, a, i, n, start; + ngx_uint_t type, class, qident, naddrs, a, i, j, start; #if (NGX_HAVE_INET6) struct in6_addr *addr6; #endif @@ -1760,7 +1760,7 @@ ngx_resolver_process_a(ngx_resolver_t *r ngx_resolver_connection_t *rec; if (ngx_resolver_copy(r, &name, buf, - buf + sizeof(ngx_resolver_hdr_t), buf + last) + buf + sizeof(ngx_resolver_hdr_t), buf + n) != NGX_OK) { return; @@ -1966,7 +1966,7 @@ ngx_resolver_process_a(ngx_resolver_t *r start = i; - while (i < last) { + while (i < n) { if (buf[i] & 0xc0) { i += 2; @@ -1992,7 +1992,7 @@ ngx_resolver_process_a(ngx_resolver_t *r found: - if (i + sizeof(ngx_resolver_an_t) >= last) { + if (i + sizeof(ngx_resolver_an_t) >= n) { goto short_response; } @@ -2032,7 +2032,7 @@ ngx_resolver_process_a(ngx_resolver_t *r goto invalid; } - if (i + 4 > last) { + if (i + 4 > n) { goto short_response; } @@ -2053,7 +2053,7 @@ ngx_resolver_process_a(ngx_resolver_t *r goto invalid; } - if (i + 16 > last) { + if (i + 16 > n) { goto short_response; } @@ -2134,7 +2134,7 @@ ngx_resolver_process_a(ngx_resolver_t *r #endif } - n = 0; + j = 0; i = ans; for (a = 0; a < nan; a++) { @@ -2163,10 +2163,10 @@ ngx_resolver_process_a(ngx_resolver_t *r if (type == NGX_RESOLVE_A) { - addr[n] = htonl((buf[i] << 24) + (buf[i + 1] << 16) + addr[j] = htonl((buf[i] << 24) + (buf[i + 1] << 16) + (buf[i + 2] << 8) + (buf[i + 3])); - if (++n == naddrs) { + if (++j == naddrs) { #if (NGX_HAVE_INET6) if (rn->naddrs6 == (u_short) -1) { @@ -2181,9 +2181,9 @@ ngx_resolver_process_a(ngx_resolver_t *r #if (NGX_HAVE_INET6) else if (type == NGX_RESOLVE_AAAA) { - ngx_memcpy(addr6[n].s6_addr, &buf[i], 16); - - if (++n == naddrs) { + ngx_memcpy(addr6[j].s6_addr, &buf[i], 16); + + if (++j == naddrs) { if (rn->naddrs == (u_short) -1) { goto next; @@ -2308,7 +2308,7 @@ ngx_resolver_process_a(ngx_resolver_t *r goto next; } - if (ngx_resolver_copy(r, &name, buf, cname, buf + last) != NGX_OK) { + if (ngx_resolver_copy(r, &name, buf, cname, buf + n) != NGX_OK) { goto failed; } From ru at nginx.com Tue Feb 2 10:48:06 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 02 Feb 2016 10:48:06 +0000 Subject: [nginx] Resolver: improved PTR response processing. Message-ID: details: http://hg.nginx.org/nginx/rev/33c4d319f08f branches: changeset: 6371:33c4d319f08f user: Ruslan Ermilov date: Thu Dec 17 17:21:16 2015 +0300 description: Resolver: improved PTR response processing. The previous code only parsed the first answer, without checking its type, and required a compressed RR name. The new code checks the RR type, supports responses with multiple answers, and doesn't require the RR name to be compressed. This has a side effect in limited support of CNAME. If a response includes both CNAME and PTR RRs, like when recursion is enabled on the server, PTR RR is handled. Full CNAME support in PTR response is not implemented in this change. diffstat: src/core/ngx_resolver.c | 118 +++++++++++++++++++++++++++++++++-------------- 1 files changed, 82 insertions(+), 36 deletions(-) diffs (138 lines): diff -r 8c8739bdd3f1 -r 33c4d319f08f src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Thu Dec 17 17:21:12 2015 +0300 +++ b/src/core/ngx_resolver.c Thu Dec 17 17:21:16 2015 +0300 @@ -2401,7 +2401,7 @@ ngx_resolver_process_ptr(ngx_resolver_t int32_t ttl; ngx_int_t octet; ngx_str_t name; - ngx_uint_t i, mask, qident, class; + ngx_uint_t mask, type, class, qident, a, i, start; ngx_queue_t *expire_queue; ngx_rbtree_t *tree; ngx_resolver_an_t *an; @@ -2554,44 +2554,90 @@ valid: i += sizeof(ngx_resolver_qs_t); - if (i + 2 + sizeof(ngx_resolver_an_t) >= n) { + for (a = 0; a < nan; a++) { + + start = i; + + while (i < n) { + + if (buf[i] & 0xc0) { + i += 2; + goto found; + } + + if (buf[i] == 0) { + i++; + goto test_length; + } + + i += 1 + buf[i]; + } + goto short_response; + + test_length: + + if (i - start < 2) { + err = "invalid name in DNS response"; + goto invalid; + } + + found: + + if (i + sizeof(ngx_resolver_an_t) >= n) { + goto short_response; + } + + an = (ngx_resolver_an_t *) &buf[i]; + + type = (an->type_hi << 8) + an->type_lo; + class = (an->class_hi << 8) + an->class_lo; + len = (an->len_hi << 8) + an->len_lo; + ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16) + + (an->ttl[2] << 8) + (an->ttl[3]); + + if (class != 1) { + ngx_log_error(r->log_level, r->log, 0, + "unexpected RR class %ui", class); + goto failed; + } + + if (ttl < 0) { + ttl = 0; + } + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, + "resolver qt:%ui cl:%ui len:%uz", + type, class, len); + + i += sizeof(ngx_resolver_an_t); + + switch (type) { + + case NGX_RESOLVE_PTR: + + goto ptr; + + case NGX_RESOLVE_CNAME: + + break; + + default: + + ngx_log_error(r->log_level, r->log, 0, + "unexpected RR type %ui", type); + } + + i += len; } - /* compression pointer to *.arpa */ - - if (buf[i] != 0xc0 || buf[i + 1] != sizeof(ngx_resolver_hdr_t)) { - err = "invalid in-addr.arpa or ip6.arpa name in DNS response"; - goto invalid; - } - - an = (ngx_resolver_an_t *) &buf[i + 2]; - - class = (an->class_hi << 8) + an->class_lo; - len = (an->len_hi << 8) + an->len_lo; - ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16) - + (an->ttl[2] << 8) + (an->ttl[3]); - - if (class != 1) { - ngx_log_error(r->log_level, r->log, 0, - "unexpected RR class %ui", class); - goto failed; - } - - if (ttl < 0) { - ttl = 0; - } - - ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, - "resolver qt:%ui cl:%ui len:%uz", - (an->type_hi << 8) + an->type_lo, - class, len); - - i += 2 + sizeof(ngx_resolver_an_t); - - if (i + len > n) { - goto short_response; - } + /* unlock addr mutex */ + + ngx_log_error(r->log_level, r->log, 0, + "no PTR type in DNS response"); + return; + +ptr: if (ngx_resolver_copy(r, &name, buf, buf + i, buf + n) != NGX_OK) { goto failed; From ru at nginx.com Tue Feb 2 10:48:09 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 02 Feb 2016 10:48:09 +0000 Subject: [nginx] Resolver: style. Message-ID: details: http://hg.nginx.org/nginx/rev/a6a5bacf6b74 branches: changeset: 6372:a6a5bacf6b74 user: Ruslan Ermilov date: Thu Dec 17 17:30:22 2015 +0300 description: Resolver: style. Use the original query name in error and debug messages when processing PTR responses. diffstat: src/core/ngx_resolver.c | 17 ++++++++--------- 1 files changed, 8 insertions(+), 9 deletions(-) diffs (78 lines): diff -r 33c4d319f08f -r a6a5bacf6b74 src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Thu Dec 17 17:21:16 2015 +0300 +++ b/src/core/ngx_resolver.c Thu Dec 17 17:30:22 2015 +0300 @@ -2396,7 +2396,6 @@ ngx_resolver_process_ptr(ngx_resolver_t { char *err; size_t len; - u_char text[NGX_SOCKADDR_STRLEN]; in_addr_t addr; int32_t ttl; ngx_int_t octet; @@ -2413,13 +2412,15 @@ ngx_resolver_process_ptr(ngx_resolver_t struct in6_addr addr6; #endif - if (ngx_resolver_copy(r, NULL, buf, + if (ngx_resolver_copy(r, &name, buf, buf + sizeof(ngx_resolver_hdr_t), buf + n) != NGX_OK) { return; } + ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name); + /* AF_INET */ addr = 0; @@ -2447,10 +2448,6 @@ ngx_resolver_process_ptr(ngx_resolver_t tree = &r->addr_rbtree; expire_queue = &r->addr_expire_queue; - addr = htonl(addr); - name.len = ngx_inet_ntop(AF_INET, &addr, text, NGX_SOCKADDR_STRLEN); - name.data = text; - goto valid; } @@ -2495,9 +2492,6 @@ invalid_in_addr_arpa: tree = &r->addr6_rbtree; expire_queue = &r->addr6_expire_queue; - name.len = ngx_inet6_ntop(addr6.s6_addr, text, NGX_SOCKADDR_STRLEN); - name.data = text; - goto valid; } @@ -2506,6 +2500,7 @@ invalid_ip6_arpa: ngx_log_error(r->log_level, r->log, 0, "invalid in-addr.arpa or ip6.arpa name in DNS response"); + ngx_resolver_free(r, name.data); return; valid: @@ -2513,6 +2508,7 @@ valid: if (rn == NULL || rn->query == NULL) { ngx_log_error(r->log_level, r->log, 0, "unexpected response for %V", &name); + ngx_resolver_free(r, name.data); goto failed; } @@ -2522,9 +2518,12 @@ valid: ngx_log_error(r->log_level, r->log, 0, "wrong ident %ui response for %V, expect %ui", ident, &name, qident); + ngx_resolver_free(r, name.data); goto failed; } + ngx_resolver_free(r, name.data); + if (code == 0 && nan == 0) { code = NGX_RESOLVE_NXDOMAIN; } From arut at nginx.com Tue Feb 2 10:53:49 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 2 Feb 2016 13:53:49 +0300 Subject: [nginx] Resolver: style. In-Reply-To: Message-ID: <20160202105349.GF17582@Romans-MacBook-Air.local> On Tue, Feb 02, 2016 at 10:48:09AM +0000, Ruslan Ermilov wrote: > details: http://hg.nginx.org/nginx/rev/a6a5bacf6b74 > branches: > changeset: 6372:a6a5bacf6b74 > user: Ruslan Ermilov > date: Thu Dec 17 17:30:22 2015 +0300 > description: > Resolver: style. > > Use the original query name in error and debug messages when > processing PTR responses. [..] On Tue, Feb 02, 2016 at 10:48:06AM +0000, Ruslan Ermilov wrote: > details: http://hg.nginx.org/nginx/rev/33c4d319f08f > branches: > changeset: 6371:33c4d319f08f > user: Ruslan Ermilov > date: Thu Dec 17 17:21:16 2015 +0300 > description: > Resolver: improved PTR response processing. > > The previous code only parsed the first answer, without checking its > type, and required a compressed RR name. > > The new code checks the RR type, supports responses with multiple > answers, and doesn't require the RR name to be compressed. > > This has a side effect in limited support of CNAME. If a response > includes both CNAME and PTR RRs, like when recursion is enabled on > the server, PTR RR is handled. > > Full CNAME support in PTR response is not implemented in this change. [..] On Tue, Feb 02, 2016 at 10:48:04AM +0000, Ruslan Ermilov wrote: > details: http://hg.nginx.org/nginx/rev/8c8739bdd3f1 > branches: > changeset: 6370:8c8739bdd3f1 > user: Ruslan Ermilov > date: Thu Dec 17 17:21:12 2015 +0300 > description: > Resolver: style. > > Renamed argument in ngx_resolver_process_a() for consistency. ??? ????? ???????. -- Roman Arutyunyan From vbart at nginx.com Tue Feb 2 13:34:32 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 02 Feb 2016 13:34:32 +0000 Subject: [nginx] HTTP/2: removed unused field from ngx_http_v2_stream_t. Message-ID: details: http://hg.nginx.org/nginx/rev/d2dc8bc0394a branches: changeset: 6373:d2dc8bc0394a user: Valentin Bartenev date: Tue Feb 02 16:33:55 2016 +0300 description: HTTP/2: removed unused field from ngx_http_v2_stream_t. diffstat: src/http/v2/ngx_http_v2.h | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r a6a5bacf6b74 -r d2dc8bc0394a src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Thu Dec 17 17:30:22 2015 +0300 +++ b/src/http/v2/ngx_http_v2.h Tue Feb 02 16:33:55 2016 +0300 @@ -167,7 +167,6 @@ struct ngx_http_v2_stream_s { ngx_http_v2_connection_t *connection; ngx_http_v2_node_t *node; - ngx_uint_t header_buffers; ngx_uint_t queued; /* From vbart at nginx.com Tue Feb 2 13:34:35 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 02 Feb 2016 13:34:35 +0000 Subject: [nginx] HTTP/2: fixed excessive memory allocation for pool cleanup. Message-ID: details: http://hg.nginx.org/nginx/rev/f598de1bfcd4 branches: changeset: 6374:f598de1bfcd4 user: Valentin Bartenev date: Tue Feb 02 16:33:55 2016 +0300 description: HTTP/2: fixed excessive memory allocation for pool cleanup. diffstat: src/http/v2/ngx_http_v2.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r d2dc8bc0394a -r f598de1bfcd4 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue Feb 02 16:33:55 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Tue Feb 02 16:33:55 2016 +0300 @@ -251,7 +251,7 @@ ngx_http_v2_init(ngx_event_t *rev) return; } - cln = ngx_pool_cleanup_add(c->pool, sizeof(ngx_pool_cleanup_file_t)); + cln = ngx_pool_cleanup_add(c->pool, 0); if (cln == NULL) { ngx_http_close_connection(c); return; From vbart at nginx.com Tue Feb 2 13:35:54 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 02 Feb 2016 13:35:54 +0000 Subject: [nginx] HTTP/2: fixed padding handling in HEADERS frame with CON... Message-ID: details: http://hg.nginx.org/nginx/rev/0e0e2e522fa2 branches: changeset: 6376:0e0e2e522fa2 user: Valentin Bartenev date: Tue Feb 02 16:33:55 2016 +0300 description: HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION. diffstat: src/http/v2/ngx_http_v2.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diffs (26 lines): diff -r e30c72b0dfda -r 0e0e2e522fa2 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue Feb 02 16:33:55 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Tue Feb 02 16:33:55 2016 +0300 @@ -1733,11 +1733,21 @@ ngx_http_v2_handle_continuation(ngx_http u_char *end, ngx_http_v2_handler_pt handler) { u_char *p; - size_t len; + size_t len, skip; uint32_t head; len = h2c->state.length; + if (h2c->state.padding && (size_t) (end - pos) > len) { + skip = ngx_min(h2c->state.padding, (end - pos) - len); + + h2c->state.padding -= skip; + + p = pos; + pos += skip; + ngx_memmove(pos, p, len); + } + if ((size_t) (end - pos) < len + NGX_HTTP_V2_FRAME_HEADER_SIZE) { return ngx_http_v2_state_save(h2c, pos, end, handler); } From arut at nginx.com Tue Feb 2 14:48:02 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Tue, 2 Feb 2016 17:48:02 +0300 Subject: [nginx] Resolver: style. In-Reply-To: <20160202105349.GF17582@Romans-MacBook-Air.local> References: <20160202105349.GF17582@Romans-MacBook-Air.local> Message-ID: <20160202144802.GH17582@Romans-MacBook-Air.local> On Tue, Feb 02, 2016 at 01:53:49PM +0300, Roman Arutyunyan wrote: > On Tue, Feb 02, 2016 at 10:48:09AM +0000, Ruslan Ermilov wrote: > > details: http://hg.nginx.org/nginx/rev/a6a5bacf6b74 > > branches: > > changeset: 6372:a6a5bacf6b74 > > user: Ruslan Ermilov > > date: Thu Dec 17 17:30:22 2015 +0300 > > description: > > Resolver: style. [..] oops, sorry, wrong list -- Roman Arutyunyan From alessandro at cloudflare.com Tue Feb 2 17:45:43 2016 From: alessandro at cloudflare.com (Alessandro Ghedini) Date: Tue, 2 Feb 2016 17:45:43 +0000 Subject: [PATCH 2 of 2] Proxy: add support for OCSP stapling verification from upstream In-Reply-To: <20160125154125.GA18601@mandy.local> References: <20160122173806.GC19316@mandy.local> <20160122174926.GK74233@mdounin.ru> <20160122180214.GA19389@mandy.local> <20160122184601.GL74233@mdounin.ru> <20160122214709.GA575@mandy.cfops.it> <20160125145929.GC9449@mdounin.ru> <20160125154125.GA18601@mandy.local> Message-ID: <20160202174543.GA90335@mandy.local> Hello, On Mon, Jan 25, 2016 at 03:41:25pm +0000, Alessandro Ghedini wrote: > > > > > > The "full" in turn doesn't seem to be correct feature, as stapled > > > > > > OCSP response may be legitimately absent for multiple reasons. > > > > > > > > > > If you control the upstream servers than I don't see any reason why you > > > > > couldn't just enable OCSP stapling unconditionally and enforce this on > > > > > the downstream with the "full" option. Maybe I'm missing something? > > > > > > > > Much like any other arbitrary requirement, this one of course can > > > > be enforced as well. The question is how this is different from > > > > other arbitrary requirements we don't provide options for. > > > > > > nginx's proxy module already supports checking CRLs, which are an even bigger > > > pain to deal with, and full OCSP has so many problems that it's not really a > > > viable option in practice (see above). As far as certificate revocation goes > > > that's it, there aren't any more "arbitrary requirements" as far as I know. so > > > it seems to me that upstreadm OCSP stapling checking would be a fairly nice and > > > useful improvement over the current status and while my patches aren't exactly > > > simple they are not that compilcated either. > > > > You are essentially trying to push "must staple" extension into > > nginx configuration. And I'm not fan of both the "must staple" > > and what you are trying to do. > > > > OCSP stapling was designed as an optimization for OCSP. That is, > > if OCSP stapling is used, it saves an OCSP lookup. But > > introducing "must staple" changes things a lot: now servers are > > required to provide OCSP responses even if they can't do so for > > some reason. You can't start answering requests till you've > > loaded an OCSP response to staple it, and you essentially never know > > if will be able to start server or not. > > > > I tend to think that "must staple" introduces much more > > complexity than it solves. And the same applies to the > > configuration directive introduced by your patch. > > Would it make a difference if I added full (not just stapling) OCSP support to > NGINX's proxy module using stapling only as an optimization as you say, or are > you against this regrdless? > > That should address your concerns I think, and the code to support OCSP is > already in place anyway. Of course it would be disabled by default, so the > decision of whether enabling it is worth the trouble would be left to the > users. Ping? Cheers From nmdilipsimha at gmail.com Wed Feb 3 18:43:06 2016 From: nmdilipsimha at gmail.com (Dilip Simha) Date: Wed, 3 Feb 2016 10:43:06 -0800 Subject: Request for information on client_body_in_single_buffer config option Message-ID: Hi, I am curious to know as to why the nginx.conf config variable: client_body_in_single_buffer is turned off by default? Is there any performance degradation when its turned on? In my understanding when this is turned on, it should help improve the performance by reading the entire body in a single memcopy operation. Isn't it? Thanks & Regards, Dilip -------------- next part -------------- An HTML attachment was scrubbed... URL: From mat999 at gmail.com Wed Feb 3 23:37:01 2016 From: mat999 at gmail.com (SplitIce) Date: Thu, 4 Feb 2016 10:37:01 +1100 Subject: Stream Module Variables Message-ID: Hi All, I have been taking a look at the Stream modules for use in a particular application. I noticed the entire subsystem lacks any variable support. - Is variable support planned? - Is there a significant reason for the omission? Regards, Mathew -------------- next part -------------- An HTML attachment was scrubbed... URL: From sam at surround.io Wed Feb 3 23:38:13 2016 From: sam at surround.io (Sam McKelvie) Date: Wed, 3 Feb 2016 15:38:13 -0800 Subject: Proposed changeset to fix client cert from ngx_ssl_get_certificate passed as HTTP header value Message-ID: <9EB22B4F-4ADC-4F74-AF39-3C2081407E94@surround.io> The ngx_ssl_get_certificate() changes ?\n? to ?\n\t? in the returned PEM string in an effort to make the string usable as an HTTP header value with $ssl_client_cert. However, bare ?\n? (without a preceding ?\r?) is passed along as ?\n\t". This causes some HTTP servers (including node/express) to hang up. This changeset fixes the problem by replacing occurrences of ?\n? that have no preceding ?\r? with "\r\n\t". Tested with node.js/express and nginx-tests. I should note that a similar solution was proposed at https://forum.nginx.org/read.php?29,249804,249833 , but the thread never went anywhere. This solution is slightly more paranoid with edge cases and does not insert extra ?\r? characters if they are already present. Thank you, Sam McKelvie # HG changeset patch # User Sam McKelvie > # Date 1454541255 28800 # Wed Feb 03 15:14:15 2016 -0800 # Node ID d70dae44196b5625f10080b4b869f33adbb83f54 # Parent 0e0e2e522fa2cb439b636a2c19aca5bdfbe8704f Fix ngx_ssl_get_certificate to properly format for HTTP header value. Previously, the value could contain lines ending in '\n' rather than '\r\n'. This caused some HTTP servers, including node/express, to reject the request entirely. Now, instances of bare '\n' are replaced with "\r\n\t". Instances of "\r\n" are still replaced with "\r\n\t". Tested with node.js/express and nginx-tests. diff -r 0e0e2e522fa2 -r d70dae44196b src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Tue Feb 02 16:33:55 2016 +0300 +++ b/src/event/ngx_event_openssl.c Wed Feb 03 15:14:15 2016 -0800 @@ -3212,7 +3212,10 @@ goto failed; } - BIO_read(bio, s->data, len); + if (BIO_read(bio, s->data, len) != (int)len) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_read() failed"); + goto failed; + } BIO_free(bio); X509_free(cert); @@ -3235,22 +3238,41 @@ size_t len; ngx_uint_t i; ngx_str_t cert; + int prev_cr; if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) { return NGX_ERROR; } + /* Strip off trailing whitespace (last newline) from the cert */ + while (cert.len > 0 && ( + cert.data[cert.len-1] == CR || + cert.data[cert.len-1] == LF || + cert.data[cert.len-1] == ' ')) { + --cert.len; + } + if (cert.len == 0) { s->len = 0; return NGX_OK; } - len = cert.len - 1; - - for (i = 0; i < cert.len - 1; i++) { + /* + * To make PEM text compatible as an HTTP header value, convert + * "\r\n" to "\r\n\t", and convert "\n" to "\r\n\t". Bare '\n' + * is rejected by some HTTP servers including node/express. + */ + prev_cr = 0; + len = 0; + for (i = 0; i < cert.len; i++) { if (cert.data[i] == LF) { - len++; + if (!prev_cr) { + len++; /* Insert CR before LF*/ + } + len++; /* Insert '\t' after LF */ } + len++; + prev_cr = (cert.data[i] == CR); } s->len = len; @@ -3261,11 +3283,18 @@ p = s->data; - for (i = 0; i < cert.len - 1; i++) { + prev_cr = 0; + for (i = 0; i < cert.len; i++) { + if (cert.data[i] == LF) { + if (!prev_cr) { + *p++ = CR; + } + *p++ = LF; + *p++ = '\t'; + } else { *p++ = cert.data[i]; - if (cert.data[i] == LF) { - *p++ = '\t'; - } + } + prev_cr = (cert.data[i] == CR); } return NGX_OK; -------------- next part -------------- An HTML attachment was scrubbed... URL: From agentzh at gmail.com Thu Feb 4 00:13:07 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Wed, 3 Feb 2016 16:13:07 -0800 Subject: Stream Module Variables In-Reply-To: References: Message-ID: Hello! On Wed, Feb 3, 2016 at 3:37 PM, SplitIce wrote: > I have been taking a look at the Stream modules for use in a particular > application. I noticed the entire subsystem lacks any variable support. > > Is variable support planned? > Is there a significant reason for the omission? > +1 I'm also looking forward to NGINX variable support in the "stream" subsystem. I'm currently emulating some of the builtin NGINX variables of the "http" subsystem in my ngx_stream_lua_module on the Lua land, like $pid, $connection, $remote_addr, $server_addr, and etc: https://github.com/openresty/stream-lua-nginx-module#nginx-api-for-lua Actually I'm also looking for "send_timeout", "send_lowat", "resolver", "resolver_timeout", "lingering_close", "lingering_time", "lingering_timeout", "postpone_output" and etc directives in the stream {} context so that each of my stream typed NGINX modules do not have to re-invent these over and over again. Best regards, -agentzh From mat999 at gmail.com Thu Feb 4 00:15:04 2016 From: mat999 at gmail.com (SplitIce) Date: Thu, 4 Feb 2016 11:15:04 +1100 Subject: Stream Module Variables In-Reply-To: References: Message-ID: The map module is also a noticeable omission tied into the lack of variables. On Thu, Feb 4, 2016 at 11:13 AM, Yichun Zhang (agentzh) wrote: > Hello! > > On Wed, Feb 3, 2016 at 3:37 PM, SplitIce wrote: > > I have been taking a look at the Stream modules for use in a particular > > application. I noticed the entire subsystem lacks any variable support. > > > > Is variable support planned? > > Is there a significant reason for the omission? > > > > +1 > > I'm also looking forward to NGINX variable support in the "stream" > subsystem. > > I'm currently emulating some of the builtin NGINX variables of the > "http" subsystem in my ngx_stream_lua_module on the Lua land, like > $pid, $connection, $remote_addr, $server_addr, and etc: > > https://github.com/openresty/stream-lua-nginx-module#nginx-api-for-lua > > Actually I'm also looking for "send_timeout", "send_lowat", > "resolver", "resolver_timeout", "lingering_close", "lingering_time", > "lingering_timeout", "postpone_output" and etc directives in the > stream {} context so that each of my stream typed NGINX modules do not > have to re-invent these over and over again. > > Best regards, > -agentzh > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Feb 4 02:05:33 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 4 Feb 2016 05:05:33 +0300 Subject: Request for information on client_body_in_single_buffer config option In-Reply-To: References: Message-ID: <20160204020533.GA70403@mdounin.ru> Hello! On Wed, Feb 03, 2016 at 10:43:06AM -0800, Dilip Simha wrote: > Hi, > > I am curious to know as to why the nginx.conf config > variable: client_body_in_single_buffer is turned off by default? > > Is there any performance degradation when its turned on? > In my understanding when this is turned on, it should help improve the > performance by reading the entire body in a single memcopy operation. Isn't > it? This option has both pros and cons: - on the one hand, it saves resources when you have to access request body as a single memory block - e.g., via $request_body variable; - on the other hand, it wastes resources when nginx is reading body from client, as it has to do an extra allocation and memcpy() if some parts of the body happened to be already read with the request header. Additonally, right now this option does not work at all and marked as TODO. See src/http/ngx_http_request_body.c for details. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Feb 4 02:26:30 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 4 Feb 2016 05:26:30 +0300 Subject: Proposed changeset to fix client cert from ngx_ssl_get_certificate passed as HTTP header value In-Reply-To: <9EB22B4F-4ADC-4F74-AF39-3C2081407E94@surround.io> References: <9EB22B4F-4ADC-4F74-AF39-3C2081407E94@surround.io> Message-ID: <20160204022630.GB70403@mdounin.ru> Hello! On Wed, Feb 03, 2016 at 03:38:13PM -0800, Sam McKelvie wrote: > The ngx_ssl_get_certificate() changes ?\n? to ?\n\t? in the returned PEM string in an effort to make > the string usable as an HTTP header value with $ssl_client_cert. However, bare ?\n? (without a preceding ?\r?) is passed > along as ?\n\t". This causes some HTTP servers (including node/express) to hang up. This changeset > fixes the problem by replacing occurrences of ?\n? that have no preceding ?\r? with "\r\n\t". > > Tested with node.js/express and nginx-tests. > > I should note that a similar solution was proposed at https://forum.nginx.org/read.php?29,249804,249833 , but the thread never went anywhere. > This solution is slightly more paranoid with edge cases and does not insert extra ?\r? characters if they are already present. IMHO, header line folding is wrong enough to don't bother with trying to fix this. It doesn't work in way too many cases including with nginx itself, and it is deprecated by RFC7230. Much better approach would be to switch to something different - may be just properly urlencoded $ssl_client_raw_cert, or plain base64 without any newlines, or whatever. -- Maxim Dounin http://nginx.org/ From mat999 at gmail.com Thu Feb 4 03:09:42 2016 From: mat999 at gmail.com (SplitIce) Date: Thu, 4 Feb 2016 14:09:42 +1100 Subject: Stream Module Message-ID: Hey All again, Quick Question regarding the Stream Module. What is the appropriate way to allocate memory during the stream? The http context has a pool member as part of the request structure, what is the equivalent in the stream module context? Thanks in Advance, Mathew -------------- next part -------------- An HTML attachment was scrubbed... URL: From nmdilipsimha at gmail.com Thu Feb 4 06:13:16 2016 From: nmdilipsimha at gmail.com (Dilip Simha) Date: Wed, 3 Feb 2016 22:13:16 -0800 Subject: Request for information on client_body_in_single_buffer config option In-Reply-To: <20160204020533.GA70403@mdounin.ru> References: <20160204020533.GA70403@mdounin.ru> Message-ID: Thank you Maxim, Regards, Dilip On Wed, Feb 3, 2016 at 6:05 PM, Maxim Dounin wrote: > Hello! > > On Wed, Feb 03, 2016 at 10:43:06AM -0800, Dilip Simha wrote: > > > Hi, > > > > I am curious to know as to why the nginx.conf config > > variable: client_body_in_single_buffer is turned off by default? > > > > Is there any performance degradation when its turned on? > > In my understanding when this is turned on, it should help improve the > > performance by reading the entire body in a single memcopy operation. > Isn't > > it? > > This option has both pros and cons: > > - on the one hand, it saves resources when you have to access > request body as a single memory block - e.g., via $request_body > variable; > > - on the other hand, it wastes resources when nginx is reading > body from client, as it has to do an extra allocation and > memcpy() if some parts of the body happened to be already read > with the request header. > > Additonally, right now this option does not work at all and marked > as TODO. See src/http/ngx_http_request_body.c for details. > > -- > 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 agentzh at gmail.com Thu Feb 4 07:30:06 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Wed, 3 Feb 2016 23:30:06 -0800 Subject: Stream Module In-Reply-To: References: Message-ID: Hello! On Wed, Feb 3, 2016 at 7:09 PM, SplitIce wrote: > What is the appropriate way to allocate memory during the stream? The http > context has a pool member as part of the request structure, what is the > equivalent in the stream module context? > I think it is s->connection->pool where s is a ngx_stream_session_t pointer. Regards, -agentzh From mat999 at gmail.com Thu Feb 4 07:50:23 2016 From: mat999 at gmail.com (SplitIce) Date: Thu, 04 Feb 2016 07:50:23 +0000 Subject: Stream Module In-Reply-To: References: Message-ID: Thanks, that's what I was using. On Thu, 4 Feb 2016, 6:30 p.m. Yichun Zhang (agentzh) wrote: > Hello! > > On Wed, Feb 3, 2016 at 7:09 PM, SplitIce wrote: > > What is the appropriate way to allocate memory during the stream? The > http > > context has a pool member as part of the request structure, what is the > > equivalent in the stream module context? > > > > I think it is s->connection->pool where s is a ngx_stream_session_t > pointer. > > Regards, > -agentzh > > _______________________________________________ > 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 maxim at nginx.com Thu Feb 4 09:29:43 2016 From: maxim at nginx.com (Maxim Konovalov) Date: Thu, 4 Feb 2016 12:29:43 +0300 Subject: Stream Module Variables In-Reply-To: References: Message-ID: <56B31A07.1080803@nginx.com> Hello, On 2/4/16 3:15 AM, SplitIce wrote: > The map module is also a noticeable omission tied into the lack > of variables. > > On Thu, Feb 4, 2016 at 11:13 AM, Yichun Zhang (agentzh) > > wrote: > > Hello! > > On Wed, Feb 3, 2016 at 3:37 PM, SplitIce wrote: >> I have been taking a look at the Stream modules for use in a >> particular application. I noticed the entire subsystem lacks >> any variable support. >> >> Is variable support planned? Is there a significant reason for >> the omission? >> > > +1 > > I'm also looking forward to NGINX variable support in the > "stream" subsystem. > > I'm currently emulating some of the builtin NGINX variables of > the "http" subsystem in my ngx_stream_lua_module on the Lua > land, like $pid, $connection, $remote_addr, $server_addr, and > etc: > > > https://github.com/openresty/stream-lua-nginx-module#nginx-api-for-lua > > > Actually I'm also looking for "send_timeout", "send_lowat", > "resolver", "resolver_timeout", "lingering_close", > "lingering_time", "lingering_timeout", "postpone_output" and etc > directives in the stream {} context so that each of my stream > typed NGINX modules do not have to re-invent these over and over > again. > Thanks for the input. This is something we have in the stream roadmap but no ETA so far. As the stream module is rather new and almost unknown for the most of nginx users we really want to collect more feedback from users about basic and missed features in the stream modules. -- Maxim Konovalov From vbart at nginx.com Thu Feb 4 15:03:53 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 04 Feb 2016 15:03:53 +0000 Subject: [nginx] HTTP/2: fixed possible buffer overrun (ticket #893). Message-ID: details: http://hg.nginx.org/nginx/rev/11e019750adc branches: changeset: 6377:11e019750adc user: Valentin Bartenev date: Thu Feb 04 18:01:04 2016 +0300 description: HTTP/2: fixed possible buffer overrun (ticket #893). Due to greater priority of the unary plus operator over the ternary operator the expression didn't work as expected. That might result in one byte less allocation than needed for the HEADERS frame buffer. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 0e0e2e522fa2 -r 11e019750adc src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Tue Feb 02 16:33:55 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Thu Feb 04 18:01:04 2016 +0300 @@ -215,8 +215,8 @@ ngx_http_v2_header_filter(ngx_http_reque clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->headers_out.server == NULL) { - len += 1 + clcf->server_tokens ? ngx_http_v2_literal_size(NGINX_VER) - : ngx_http_v2_literal_size("nginx"); + len += 1 + (clcf->server_tokens ? ngx_http_v2_literal_size(NGINX_VER) + : ngx_http_v2_literal_size("nginx")); } if (r->headers_out.date == NULL) { From sam at surround.io Thu Feb 4 17:17:31 2016 From: sam at surround.io (Sam McKelvie) Date: Thu, 4 Feb 2016 09:17:31 -0800 Subject: Proposed changeset to fix client cert from ngx_ssl_get_certificate passed as HTTP header value Message-ID: > Hello! > > On Wed, Feb 03, 2016 at 03:38:13PM -0800, Sam McKelvie wrote: > >> The ngx_ssl_get_certificate() changes ?\n? to ?\n\t? in the returned PEM string in an effort to make >> the string usable as an HTTP header value with $ssl_client_cert. However, bare ?\n? (without a preceding ?\r?) is passed >> along as ?\n\t". This causes some HTTP servers (including node/express) to hang up. This changeset >> fixes the problem by replacing occurrences of ?\n? that have no preceding ?\r? with "\r\n\t". >> >> Tested with node.js/express and nginx-tests. >> >> I should note that a similar solution was proposed at https://forum.nginx.org/read.php?29,249804,249833 , but the thread never went anywhere. >> This solution is slightly more paranoid with edge cases and does not insert extra ?\r? characters if they are already present. > > IMHO, header line folding is wrong enough to don't bother with > trying to fix this. It doesn't work in way too many cases > including with nginx itself, and it is deprecated by RFC7230. > > Much better approach would be to switch to something different - > may be just properly urlencoded $ssl_client_raw_cert, or plain > base64 without any newlines, or whatever. > I tend to agree. However, nix_ssl_get_certificate() is already folding the certificate for HTTP headers by inserting '\t' at the beginning of each line, so that seems to be its primary purpose. I can?t change that function to return anything that is not itself a valid PEM certificate, or it would certainly break any existing applications that parse the results. So unless you think it is OK to tweak it to insert '\r' as well, I think you are saying this function is just permanently unusable for the purposes of passing a certificate in a header. Would you be more amenable to defining a new "$ssl_base64_client_cert" or ?$ssl_escaped_client_cert? variable that is a properly encoded PEM string? Would you prefer base64 (which would greatly increase the size) or a quoted-string for with backslashes to escape control characters? I would be willing to submit such a changeset? Sam > -- > Maxim Dounin > http://nginx.org/ From mdounin at mdounin.ru Thu Feb 4 18:29:28 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 4 Feb 2016 21:29:28 +0300 Subject: Proposed changeset to fix client cert from ngx_ssl_get_certificate passed as HTTP header value In-Reply-To: References: Message-ID: <20160204182928.GF70403@mdounin.ru> Hello! On Thu, Feb 04, 2016 at 09:17:31AM -0800, Sam McKelvie wrote: > > Hello! > > > > On Wed, Feb 03, 2016 at 03:38:13PM -0800, Sam McKelvie wrote: > > > >> The ngx_ssl_get_certificate() changes ?\n? to ?\n\t? in the returned PEM string in an effort to make > >> the string usable as an HTTP header value with $ssl_client_cert. However, bare ?\n? (without a preceding ?\r?) is passed > >> along as ?\n\t". This causes some HTTP servers (including node/express) to hang up. This changeset > >> fixes the problem by replacing occurrences of ?\n? that have no preceding ?\r? with "\r\n\t". > >> > >> Tested with node.js/express and nginx-tests. > >> > >> I should note that a similar solution was proposed at https://forum.nginx.org/read.php?29,249804,249833 , but the thread never went anywhere. > >> This solution is slightly more paranoid with edge cases and does not insert extra ?\r? characters if they are already present. > > > > IMHO, header line folding is wrong enough to don't bother with > > trying to fix this. It doesn't work in way too many cases > > including with nginx itself, and it is deprecated by RFC7230. > > > > Much better approach would be to switch to something different - > > may be just properly urlencoded $ssl_client_raw_cert, or plain > > base64 without any newlines, or whatever. > > > I tend to agree. However, nix_ssl_get_certificate() is already folding > the certificate for HTTP headers by inserting '\t' at the beginning of > each line, so that seems to be its primary purpose. I can?t change > that function to return anything that is not itself a valid PEM > certificate, or it would certainly break any existing applications > that parse the results. So unless you think it is OK to tweak it to > insert '\r' as well, I think you are saying this function is just > permanently unusable for the purposes of passing a certificate in a > header. Current implementation is usable where it is currently used. Most servers happen to parse "\n" without "\r" just fine. RFC2616 explicitly recommends applications to accept bare LF, http://tools.ietf.org/html/rfc2616#section-19.3: The line terminator for message-header fields is the sequence CRLF. However, we recommend that applications, when parsing such headers, recognize a single LF as a line terminator and ignore the leading CR. On the other hand, any changes, even minor ones like adding "\r", may break existing applications who use $ssl_client_cert. And if we are goint to introduce changes - it's better to change it something more useable than header folding. > Would you be more amenable to defining a new "$ssl_base64_client_cert" > or ?$ssl_escaped_client_cert? variable that is a properly encoded PEM > string? Would you prefer base64 (which would greatly increase the > size) or a quoted-string for with backslashes to escape control > characters? I would be willing to submit such a changeset? For sure base64-encoded PEM is not something we want, that would be double base64 encoding and makes no sense. Base64-encoded DER (== PEM without header/footer/newlines) may be an option. I tend to think that we want to use URI escaping here. We already do this in mail for Auth-SSL-Cert header, with minimal escaping. As we don't know context for the variable - it probably would be a better option to escape it as an URI component. Tricky part here is to understand what we are going to do with the $ssl_client_cert variable. I don't like the idea of preserving it in "PEM with tab added for header folding" forever. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Feb 4 18:40:30 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 04 Feb 2016 18:40:30 +0000 Subject: [nginx] Dynamic modules: moved module-related stuff to separate ... Message-ID: details: http://hg.nginx.org/nginx/rev/0f203a2af17c branches: changeset: 6378:0f203a2af17c user: Maxim Dounin date: Thu Feb 04 18:30:21 2016 +0300 description: Dynamic modules: moved module-related stuff to separate files. diffstat: auto/sources | 2 + src/core/nginx.c | 7 +--- src/core/ngx_conf_file.h | 51 --------------------------------- src/core/ngx_core.h | 1 + src/core/ngx_cycle.c | 10 +---- src/core/ngx_module.c | 65 ++++++++++++++++++++++++++++++++++++++++++ src/core/ngx_module.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ src/event/ngx_event.c | 9 +----- src/http/ngx_http.c | 9 +----- src/mail/ngx_mail.c | 9 +----- src/stream/ngx_stream.c | 9 +----- 11 files changed, 151 insertions(+), 95 deletions(-) diffs (truncated from 365 to 300 lines): diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -36,6 +36,7 @@ CORE_DEPS="src/core/nginx.h \ src/core/ngx_connection.h \ src/core/ngx_cycle.h \ src/core/ngx_conf_file.h \ + src/core/ngx_module.h \ src/core/ngx_resolver.h \ src/core/ngx_open_file_cache.h \ src/core/ngx_crypt.h \ @@ -71,6 +72,7 @@ CORE_SRCS="src/core/nginx.c \ src/core/ngx_rwlock.c \ src/core/ngx_cpuinfo.c \ src/core/ngx_conf_file.c \ + src/core/ngx_module.c \ src/core/ngx_resolver.c \ src/core/ngx_open_file_cache.c \ src/core/ngx_crypt.c \ diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -160,8 +160,6 @@ ngx_module_t ngx_core_module = { }; -ngx_uint_t ngx_max_module; - static ngx_uint_t ngx_show_help; static ngx_uint_t ngx_show_version; static ngx_uint_t ngx_show_configure; @@ -260,9 +258,8 @@ main(int argc, char *const *argv) return 1; } - ngx_max_module = 0; - for (i = 0; ngx_modules[i]; i++) { - ngx_modules[i]->index = ngx_max_module++; + if (ngx_preinit_modules() != NGX_OK) { + return 1; } cycle = ngx_init_cycle(&init_cycle); diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -96,53 +96,6 @@ struct ngx_open_file_s { }; -#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1 -#define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0 - -struct ngx_module_s { - ngx_uint_t ctx_index; - ngx_uint_t index; - - ngx_uint_t spare0; - ngx_uint_t spare1; - ngx_uint_t spare2; - ngx_uint_t spare3; - - ngx_uint_t version; - - void *ctx; - ngx_command_t *commands; - ngx_uint_t type; - - ngx_int_t (*init_master)(ngx_log_t *log); - - ngx_int_t (*init_module)(ngx_cycle_t *cycle); - - ngx_int_t (*init_process)(ngx_cycle_t *cycle); - ngx_int_t (*init_thread)(ngx_cycle_t *cycle); - void (*exit_thread)(ngx_cycle_t *cycle); - void (*exit_process)(ngx_cycle_t *cycle); - - void (*exit_master)(ngx_cycle_t *cycle); - - uintptr_t spare_hook0; - uintptr_t spare_hook1; - uintptr_t spare_hook2; - uintptr_t spare_hook3; - uintptr_t spare_hook4; - uintptr_t spare_hook5; - uintptr_t spare_hook6; - uintptr_t spare_hook7; -}; - - -typedef struct { - ngx_str_t name; - void *(*create_conf)(ngx_cycle_t *cycle); - char *(*init_conf)(ngx_cycle_t *cycle, void *conf); -} ngx_core_module_t; - - typedef struct { ngx_file_t file; ngx_buf_t *buffer; @@ -340,8 +293,4 @@ char *ngx_conf_set_enum_slot(ngx_conf_t char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -extern ngx_uint_t ngx_max_module; -extern ngx_module_t *ngx_modules[]; - - #endif /* _NGX_CONF_FILE_H_INCLUDED_ */ 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 @@ -83,6 +83,7 @@ typedef void (*ngx_connection_handler_pt #endif #include #include +#include #include #include #include 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 @@ -612,13 +612,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) pool->log = cycle->log; - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->init_module) { - if (ngx_modules[i]->init_module(cycle) != NGX_OK) { - /* fatal */ - exit(1); - } - } + if (ngx_init_modules(cycle) != NGX_OK) { + /* fatal */ + exit(1); } diff --git a/src/core/ngx_module.c b/src/core/ngx_module.c new file mode 100644 --- /dev/null +++ b/src/core/ngx_module.c @@ -0,0 +1,65 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Maxim Dounin + * Copyright (C) Nginx, Inc. + */ + + +#include +#include + + +ngx_uint_t ngx_max_module; + + +ngx_int_t +ngx_preinit_modules() +{ + ngx_uint_t i; + + ngx_max_module = 0; + for (i = 0; ngx_modules[i]; i++) { + ngx_modules[i]->index = ngx_max_module++; + } + + return NGX_OK; +} + + +ngx_int_t +ngx_init_modules(ngx_cycle_t *cycle) +{ + ngx_uint_t i; + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->init_module) { + if (ngx_modules[i]->init_module(cycle) != NGX_OK) { + return NGX_ERROR; + } + } + } + + return NGX_OK; +} + + +ngx_int_t +ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type) +{ + ngx_uint_t i, max; + + max = 0; + + /* count appropriate modules, set up their indices */ + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->type != type) { + continue; + } + + ngx_modules[i]->ctx_index = max++; + } + + return max; +} diff --git a/src/core/ngx_module.h b/src/core/ngx_module.h new file mode 100644 --- /dev/null +++ b/src/core/ngx_module.h @@ -0,0 +1,74 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Maxim Dounin + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_MODULE_H_INCLUDED_ +#define _NGX_MODULE_H_INCLUDED_ + + +#include +#include + + +#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1 +#define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0 + + +struct ngx_module_s { + ngx_uint_t ctx_index; + ngx_uint_t index; + + ngx_uint_t spare0; + ngx_uint_t spare1; + ngx_uint_t spare2; + ngx_uint_t spare3; + + ngx_uint_t version; + + void *ctx; + ngx_command_t *commands; + ngx_uint_t type; + + ngx_int_t (*init_master)(ngx_log_t *log); + + ngx_int_t (*init_module)(ngx_cycle_t *cycle); + + ngx_int_t (*init_process)(ngx_cycle_t *cycle); + ngx_int_t (*init_thread)(ngx_cycle_t *cycle); + void (*exit_thread)(ngx_cycle_t *cycle); + void (*exit_process)(ngx_cycle_t *cycle); + + void (*exit_master)(ngx_cycle_t *cycle); + + uintptr_t spare_hook0; + uintptr_t spare_hook1; + uintptr_t spare_hook2; + uintptr_t spare_hook3; + uintptr_t spare_hook4; + uintptr_t spare_hook5; + uintptr_t spare_hook6; + uintptr_t spare_hook7; +}; + + +typedef struct { + ngx_str_t name; + void *(*create_conf)(ngx_cycle_t *cycle); + char *(*init_conf)(ngx_cycle_t *cycle, void *conf); +} ngx_core_module_t; + + +ngx_int_t ngx_preinit_modules(); +ngx_int_t ngx_init_modules(ngx_cycle_t *cycle); +ngx_int_t ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type); + + +extern ngx_module_t *ngx_modules[]; +extern ngx_uint_t ngx_max_module; + + +#endif /* _NGX_MODULE_H_INCLUDED_ */ diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -891,14 +891,7 @@ ngx_events_block(ngx_conf_t *cf, ngx_com /* count the number of the event modules and set up their indices */ - ngx_event_max_module = 0; - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_EVENT_MODULE) { - continue; From mdounin at mdounin.ru Thu Feb 4 18:40:33 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 04 Feb 2016 18:40:33 +0000 Subject: [nginx] Dynamic modules: changed ngx_modules to cycle->modules. Message-ID: details: http://hg.nginx.org/nginx/rev/cf5e822cf470 branches: changeset: 6379:cf5e822cf470 user: Maxim Dounin date: Thu Feb 04 18:30:21 2016 +0300 description: Dynamic modules: changed ngx_modules to cycle->modules. diffstat: src/core/ngx_conf_file.c | 14 ++++---- src/core/ngx_cycle.c | 20 ++++++++----- src/core/ngx_cycle.h | 2 + src/core/ngx_module.c | 12 ++++---- src/event/ngx_event.c | 44 +++++++++++++++-------------- src/http/modules/ngx_http_rewrite_module.c | 8 ++-- src/http/ngx_http.c | 28 +++++++++--------- src/http/ngx_http_core_module.c | 28 +++++++++--------- src/http/ngx_http_upstream.c | 10 +++--- src/mail/ngx_mail.c | 16 +++++----- src/mail/ngx_mail_core_module.c | 20 ++++++------ src/os/unix/ngx_process_cycle.c | 30 ++++++++++---------- src/os/win32/ngx_process_cycle.c | 18 ++++++------ src/stream/ngx_stream.c | 22 +++++++------- src/stream/ngx_stream_core_module.c | 8 ++-- src/stream/ngx_stream_upstream.c | 8 ++-- 16 files changed, 148 insertions(+), 140 deletions(-) diffs (truncated from 796 to 300 lines): diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -329,9 +329,9 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int found = 0; - for (i = 0; ngx_modules[i]; i++) { + for (i = 0; cf->cycle->modules[i]; i++) { - cmd = ngx_modules[i]->commands; + cmd = cf->cycle->modules[i]->commands; if (cmd == NULL) { continue; } @@ -348,8 +348,8 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int found = 1; - if (ngx_modules[i]->type != NGX_CONF_MODULE - && ngx_modules[i]->type != cf->module_type) + if (cf->cycle->modules[i]->type != NGX_CONF_MODULE + && cf->cycle->modules[i]->type != cf->module_type) { continue; } @@ -411,16 +411,16 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int conf = NULL; if (cmd->type & NGX_DIRECT_CONF) { - conf = ((void **) cf->ctx)[ngx_modules[i]->index]; + conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index]; } else if (cmd->type & NGX_MAIN_CONF) { - conf = &(((void **) cf->ctx)[ngx_modules[i]->index]); + conf = &(((void **) cf->ctx)[cf->cycle->modules[i]->index]); } else if (cf->ctx) { confp = *(void **) ((char *) cf->ctx + cmd->conf); if (confp) { - conf = confp[ngx_modules[i]->ctx_index]; + conf = confp[cf->cycle->modules[i]->ctx_index]; } } 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 @@ -212,12 +212,15 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len); - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_CORE_MODULE) { + cycle->modules = ngx_modules; + + + for (i = 0; cycle->modules[i]; i++) { + if (cycle->modules[i]->type != NGX_CORE_MODULE) { continue; } - module = ngx_modules[i]->ctx; + module = cycle->modules[i]->ctx; if (module->create_conf) { rv = module->create_conf(cycle); @@ -225,7 +228,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) ngx_destroy_pool(pool); return NULL; } - cycle->conf_ctx[ngx_modules[i]->index] = rv; + cycle->conf_ctx[cycle->modules[i]->index] = rv; } } @@ -276,15 +279,16 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) cycle->conf_file.data); } - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_CORE_MODULE) { + for (i = 0; cycle->modules[i]; i++) { + if (cycle->modules[i]->type != NGX_CORE_MODULE) { continue; } - module = ngx_modules[i]->ctx; + module = cycle->modules[i]->ctx; if (module->init_conf) { - if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index]) + if (module->init_conf(cycle, + cycle->conf_ctx[cycle->modules[i]->index]) == NGX_CONF_ERROR) { environ = senv; diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -48,6 +48,8 @@ struct ngx_cycle_s { ngx_connection_t *free_connections; ngx_uint_t free_connection_n; + ngx_module_t **modules; + ngx_queue_t reusable_connections_queue; ngx_array_t listening; diff --git a/src/core/ngx_module.c b/src/core/ngx_module.c --- a/src/core/ngx_module.c +++ b/src/core/ngx_module.c @@ -32,9 +32,9 @@ ngx_init_modules(ngx_cycle_t *cycle) { ngx_uint_t i; - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->init_module) { - if (ngx_modules[i]->init_module(cycle) != NGX_OK) { + for (i = 0; cycle->modules[i]; i++) { + if (cycle->modules[i]->init_module) { + if (cycle->modules[i]->init_module(cycle) != NGX_OK) { return NGX_ERROR; } } @@ -53,12 +53,12 @@ ngx_count_modules(ngx_cycle_t *cycle, ng /* count appropriate modules, set up their indices */ - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != type) { + for (i = 0; cycle->modules[i]; i++) { + if (cycle->modules[i]->type != type) { continue; } - ngx_modules[i]->ctx_index = max++; + cycle->modules[i]->ctx_index = max++; } return max; diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -606,16 +606,16 @@ ngx_event_process_init(ngx_cycle_t *cycl return NGX_ERROR; } - for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_EVENT_MODULE) { + for (m = 0; cycle->modules[m]; m++) { + if (cycle->modules[m]->type != NGX_EVENT_MODULE) { continue; } - if (ngx_modules[m]->ctx_index != ecf->use) { + if (cycle->modules[m]->ctx_index != ecf->use) { continue; } - module = ngx_modules[m]->ctx; + module = cycle->modules[m]->ctx; if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) { /* fatal */ @@ -905,16 +905,17 @@ ngx_events_block(ngx_conf_t *cf, ngx_com *(void **) conf = ctx; - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_EVENT_MODULE) { + for (i = 0; cf->cycle->modules[i]; i++) { + if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) { continue; } - m = ngx_modules[i]->ctx; + m = cf->cycle->modules[i]->ctx; if (m->create_conf) { - (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle); - if ((*ctx)[ngx_modules[i]->ctx_index] == NULL) { + (*ctx)[cf->cycle->modules[i]->ctx_index] = + m->create_conf(cf->cycle); + if ((*ctx)[cf->cycle->modules[i]->ctx_index] == NULL) { return NGX_CONF_ERROR; } } @@ -933,15 +934,16 @@ ngx_events_block(ngx_conf_t *cf, ngx_com return rv; } - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_EVENT_MODULE) { + for (i = 0; cf->cycle->modules[i]; i++) { + if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) { continue; } - m = ngx_modules[i]->ctx; + m = cf->cycle->modules[i]->ctx; if (m->init_conf) { - rv = m->init_conf(cf->cycle, (*ctx)[ngx_modules[i]->ctx_index]); + rv = m->init_conf(cf->cycle, + (*ctx)[cf->cycle->modules[i]->ctx_index]); if (rv != NGX_CONF_OK) { return rv; } @@ -1002,15 +1004,15 @@ ngx_event_use(ngx_conf_t *cf, ngx_comman } - for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_EVENT_MODULE) { + for (m = 0; cf->cycle->modules[m]; m++) { + if (cf->cycle->modules[m]->type != NGX_EVENT_MODULE) { continue; } - module = ngx_modules[m]->ctx; + module = cf->cycle->modules[m]->ctx; if (module->name->len == value[1].len) { if (ngx_strcmp(module->name->data, value[1].data) == 0) { - ecf->use = ngx_modules[m]->ctx_index; + ecf->use = cf->cycle->modules[m]->ctx_index; ecf->name = module->name->data; if (ngx_process == NGX_PROCESS_SINGLE @@ -1225,20 +1227,20 @@ ngx_event_core_init_conf(ngx_cycle_t *cy #endif if (module == NULL) { - for (i = 0; ngx_modules[i]; i++) { + for (i = 0; cycle->modules[i]; i++) { - if (ngx_modules[i]->type != NGX_EVENT_MODULE) { + if (cycle->modules[i]->type != NGX_EVENT_MODULE) { continue; } - event_module = ngx_modules[i]->ctx; + event_module = cycle->modules[i]->ctx; if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0) { continue; } - module = ngx_modules[i]; + module = cycle->modules[i]; break; } } diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -560,12 +560,12 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_ return NGX_CONF_ERROR; } - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE) { + for (i = 0; cf->cycle->modules[i]; i++) { + if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) { continue; } - module = ngx_modules[i]->ctx; + module = cf->cycle->modules[i]->ctx; if (module->create_loc_conf) { @@ -574,7 +574,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_ return NGX_CONF_ERROR; } - ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf; + ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf; } } diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -183,13 +183,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma * of the all http modules */ - for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_HTTP_MODULE) { + for (m = 0; cf->cycle->modules[m]; m++) { + if (cf->cycle->modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = ngx_modules[m]->ctx; - mi = ngx_modules[m]->ctx_index; + module = cf->cycle->modules[m]->ctx; From mdounin at mdounin.ru Thu Feb 4 18:40:35 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 04 Feb 2016 18:40:35 +0000 Subject: [nginx] Dynamic modules: dlopen() support. Message-ID: details: http://hg.nginx.org/nginx/rev/7142b04337d6 branches: changeset: 6380:7142b04337d6 user: Maxim Dounin date: Thu Feb 04 18:30:21 2016 +0300 description: Dynamic modules: dlopen() support. diffstat: auto/lib/openssl/conf | 3 +-- auto/sources | 4 ++++ auto/unix | 4 ++-- src/core/ngx_core.h | 1 + src/os/unix/ngx_darwin_config.h | 2 ++ src/os/unix/ngx_dlopen.c | 28 ++++++++++++++++++++++++++++ src/os/unix/ngx_dlopen.h | 31 +++++++++++++++++++++++++++++++ src/os/unix/ngx_freebsd_config.h | 2 ++ src/os/unix/ngx_linux_config.h | 2 ++ src/os/unix/ngx_posix_config.h | 5 +++++ src/os/unix/ngx_solaris_config.h | 2 ++ src/os/win32/ngx_dlopen.c | 22 ++++++++++++++++++++++ src/os/win32/ngx_dlopen.h | 32 ++++++++++++++++++++++++++++++++ 13 files changed, 134 insertions(+), 4 deletions(-) diffs (283 lines): diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf --- a/auto/lib/openssl/conf +++ b/auto/lib/openssl/conf @@ -32,7 +32,6 @@ if [ $OPENSSL != NONE ]; then CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h" CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a" CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a" - CORE_LIBS="$CORE_LIBS $NGX_LIBDL" if [ "$NGX_PLATFORM" = win32 ]; then CORE_LIBS="$CORE_LIBS -lgdi32 -lcrypt32 -lws2_32" @@ -106,7 +105,7 @@ else if [ $ngx_found = yes ]; then have=NGX_SSL . auto/have CORE_INCS="$CORE_INCS $ngx_feature_path" - CORE_LIBS="$CORE_LIBS $ngx_feature_libs $NGX_LIBDL" + CORE_LIBS="$CORE_LIBS $ngx_feature_libs" OPENSSL=YES fi fi diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -152,6 +152,7 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \ src/os/unix/ngx_socket.h \ src/os/unix/ngx_os.h \ src/os/unix/ngx_user.h \ + src/os/unix/ngx_dlopen.h \ src/os/unix/ngx_process_cycle.h" # add to UNIX_DEPS @@ -183,6 +184,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/unix/ngx_setproctitle.c \ src/os/unix/ngx_posix_init.c \ src/os/unix/ngx_user.c \ + src/os/unix/ngx_dlopen.c \ src/os/unix/ngx_process_cycle.c" POSIX_DEPS=src/os/unix/ngx_posix_config.h @@ -228,6 +230,7 @@ WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \ src/os/win32/ngx_socket.h \ src/os/win32/ngx_os.h \ src/os/win32/ngx_user.h \ + src/os/win32/ngx_dlopen.h \ src/os/win32/ngx_process_cycle.h" WIN32_CONFIG=src/os/win32/ngx_win32_config.h @@ -248,6 +251,7 @@ WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/win32/ngx_wsasend_chain.c \ src/os/win32/ngx_win32_init.c \ src/os/win32/ngx_user.c \ + src/os/win32/ngx_dlopen.c \ src/os/win32/ngx_event_log.c \ src/os/win32/ngx_process_cycle.c \ src/event/ngx_event_acceptex.c" diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -255,7 +255,7 @@ ngx_feature_test="struct statvfs fs; ngx_feature="dlopen()" -ngx_feature_name= +ngx_feature_name="NGX_HAVE_DLOPEN" ngx_feature_run=no ngx_feature_incs="#include " ngx_feature_path= @@ -271,7 +271,7 @@ if [ $ngx_found != yes ]; then . auto/feature if [ $ngx_found = yes ]; then - NGX_LIBDL="-ldl" + CORE_LIBS="$CORE_LIBS -ldl" fi fi 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 @@ -53,6 +53,7 @@ typedef void (*ngx_connection_handler_pt #include #include #include +#include #include #include #include diff --git a/src/os/unix/ngx_darwin_config.h b/src/os/unix/ngx_darwin_config.h --- a/src/os/unix/ngx_darwin_config.h +++ b/src/os/unix/ngx_darwin_config.h @@ -48,6 +48,8 @@ #include #include +#include + #ifndef IOV_MAX #define IOV_MAX 64 diff --git a/src/os/unix/ngx_dlopen.c b/src/os/unix/ngx_dlopen.c new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_dlopen.c @@ -0,0 +1,28 @@ + +/* + * Copyright (C) Maxim Dounin + * Copyright (C) Nginx, Inc. + */ + + +#include +#include + + +#if (NGX_HAVE_DLOPEN) + +char * +ngx_dlerror(void) +{ + char *err; + + err = (char *) dlerror(); + + if (err == NULL) { + return ""; + } + + return err; +} + +#endif diff --git a/src/os/unix/ngx_dlopen.h b/src/os/unix/ngx_dlopen.h new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_dlopen.h @@ -0,0 +1,31 @@ + +/* + * Copyright (C) Maxim Dounin + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_DLOPEN_H_INCLUDED_ +#define _NGX_DLOPEN_H_INCLUDED_ + + +#include +#include + + +#define ngx_dlopen(path) dlopen((char *) path, RTLD_NOW | RTLD_GLOBAL) +#define ngx_dlopen_n "dlopen()" + +#define ngx_dlsym(handle, symbol) dlsym(handle, symbol) +#define ngx_dlsym_n "dlsym()" + +#define ngx_dlclose(handle) dlclose(handle) +#define ngx_dlclose_n "dlclose()" + + +#if (NGX_HAVE_DLOPEN) +char *ngx_dlerror(void); +#endif + + +#endif /* _NGX_DLOPEN_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -49,6 +49,8 @@ #include #include +#include + #if __FreeBSD_version < 400017 diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -55,6 +55,8 @@ #include #include /* uname() */ +#include + #include diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h --- a/src/os/unix/ngx_posix_config.h +++ b/src/os/unix/ngx_posix_config.h @@ -108,6 +108,11 @@ #include +#if (NGX_HAVE_DLOPEN) +#include +#endif + + #if (NGX_HAVE_POSIX_SEM) #include #endif diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h --- a/src/os/unix/ngx_solaris_config.h +++ b/src/os/unix/ngx_solaris_config.h @@ -55,6 +55,8 @@ #include #include +#include + #define NGX_ALIGNMENT _MAX_ALIGNMENT #include diff --git a/src/os/win32/ngx_dlopen.c b/src/os/win32/ngx_dlopen.c new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_dlopen.c @@ -0,0 +1,22 @@ + +/* + * Copyright (C) Maxim Dounin + * Copyright (C) Nginx, Inc. + */ + + +#include +#include + + +char * +ngx_dlerror(void) +{ + u_char *p; + static u_char errstr[NGX_MAX_ERROR_STR]; + + p = ngx_strerror(ngx_errno, errstr, NGX_MAX_ERROR_STR); + *p = '\0'; + + return (char *) errstr; +} diff --git a/src/os/win32/ngx_dlopen.h b/src/os/win32/ngx_dlopen.h new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_dlopen.h @@ -0,0 +1,32 @@ + +/* + * Copyright (C) Maxim Dounin + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_DLOPEN_H_INCLUDED_ +#define _NGX_DLOPEN_H_INCLUDED_ + + +#include +#include + + +#define NGX_HAVE_DLOPEN 1 + + +#define ngx_dlopen(path) LoadLibrary((char *) path) +#define ngx_dlopen_n "LoadLibrary()" + +#define ngx_dlsym(handle, symbol) (void *) GetProcAddress(handle, symbol) +#define ngx_dlsym_n "GetProcAddress()" + +#define ngx_dlclose(handle) (FreeLibrary(handle) ? 0 : -1) +#define ngx_dlclose_n "FreeLibrary()" + + +char *ngx_dlerror(void); + + +#endif /* _NGX_DLOPEN_H_INCLUDED_ */ From mdounin at mdounin.ru Thu Feb 4 18:40:38 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 04 Feb 2016 18:40:38 +0000 Subject: [nginx] Dynamic modules: introduced HTTP_INIT_FILTER_MODULES. Message-ID: details: http://hg.nginx.org/nginx/rev/c529555949b7 branches: changeset: 6381:c529555949b7 user: Maxim Dounin date: Thu Feb 04 18:30:21 2016 +0300 description: Dynamic modules: introduced HTTP_INIT_FILTER_MODULES. Additionally, HTTP_HEADERS_FILTER_MODULE now added to HTTP_FILTER_MODULES. This avoids explict use of modules at the later stages, now only module lists are used. This will be needed in later patches. diffstat: auto/modules | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-) diffs (37 lines): diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -185,10 +185,17 @@ if [ $HTTP_USERID = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_USERID_SRCS" fi +HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_HEADERS_FILTER_MODULE" + + +HTTP_INIT_FILTER_MODULES="$HTTP_COPY_FILTER_MODULE \ + $HTTP_RANGE_BODY_FILTER_MODULE \ + $HTTP_NOT_MODIFIED_FILTER_MODULE" + if [ $HTTP_SLICE = YES ]; then HTTP_SRCS="$HTTP_SRCS $HTTP_SLICE_SRCS" -else - HTTP_SLICE_FILTER_MODULE="" + HTTP_INIT_FILTER_MODULES="$HTTP_INIT_FILTER_MODULES \ + $HTTP_SLICE_FILTER_MODULE" fi @@ -469,12 +476,7 @@ fi if [ $HTTP = YES ]; then modules="$modules $HTTP_MODULES $HTTP_FILTER_MODULES \ - $HTTP_HEADERS_FILTER_MODULE \ - $HTTP_AUX_FILTER_MODULES \ - $HTTP_COPY_FILTER_MODULE \ - $HTTP_RANGE_BODY_FILTER_MODULE \ - $HTTP_NOT_MODIFIED_FILTER_MODULE \ - $HTTP_SLICE_FILTER_MODULE" + $HTTP_AUX_FILTER_MODULES $HTTP_INIT_FILTER_MODULES" NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(HTTP_DEPS)" fi From mdounin at mdounin.ru Thu Feb 4 18:40:40 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 04 Feb 2016 18:40:40 +0000 Subject: [nginx] Dynamic modules: auto/module script. Message-ID: details: http://hg.nginx.org/nginx/rev/392959224560 branches: changeset: 6382:392959224560 user: Maxim Dounin date: Thu Feb 04 18:30:21 2016 +0300 description: Dynamic modules: auto/module script. This script simplifies configuration of additional modules, including 3rd party ones. The script is extensible, and will be used to introduce dynamic linking of modules in upcoming changes. 3rd party module config scripts are called with ngx_module_link preset to "ADDON" - this allows config scripts to call auto/module without ngx_module_link explicitly defined, as well as testing if new interface is in place if compatibility with older nginx versions is desired. In collaboration with Ruslan Ermilov. diffstat: auto/make | 6 +- auto/module | 71 ++++ auto/modules | 979 ++++++++++++++++++++++++++++++++++++++++++++++------------ auto/sources | 350 --------------------- 4 files changed, 848 insertions(+), 558 deletions(-) diffs (truncated from 1691 to 300 lines): diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -148,7 +148,7 @@ END fi -ngx_all_srcs="$ngx_all_srcs $NGX_MISC_SRCS" +ngx_all_srcs="$ngx_all_srcs $MISC_SRCS" if test -n "$NGX_ADDON_SRCS"; then @@ -365,11 +365,11 @@ fi # the misc sources -if test -n "$NGX_MISC_SRCS"; then +if test -n "$MISC_SRCS"; then ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" - for ngx_src in $NGX_MISC_SRCS + for ngx_src in $MISC_SRCS do ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` ngx_obj=`echo $ngx_src \ diff --git a/auto/module b/auto/module new file mode 100644 --- /dev/null +++ b/auto/module @@ -0,0 +1,71 @@ + +# Copyright (C) Ruslan Ermilov +# Copyright (C) Nginx, Inc. + + +case $ngx_module_type in + HTTP_*) ngx_var=HTTP ;; + *) ngx_var=$ngx_module_type ;; +esac + + +if [ "$ngx_module_link" = YES ]; then + + eval ${ngx_module_type}_MODULES=\"\$${ngx_module_type}_MODULES \ + $ngx_module_name\" + + eval ${ngx_var}_SRCS=\"\$${ngx_var}_SRCS $ngx_module_srcs\" + + if test -n "$ngx_module_incs"; then + eval ${ngx_var}_INCS=\"\$${ngx_var}_INCS $ngx_module_incs\" + fi + + if test -n "$ngx_module_deps"; then + eval ${ngx_var}_DEPS=\"\$${ngx_var}_DEPS $ngx_module_deps\" + fi + + for lib in $ngx_module_libs + do + case $lib in + + PCRE | OPENSSL | MD5 | SHA1 | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP) + eval USE_${lib}=YES + ;; + + *) + CORE_LIBS="$CORE_LIBS $lib" + ;; + + esac + done + +elif [ "$ngx_module_link" = ADDON ]; then + + eval ${ngx_module_type}_MODULES=\"\$${ngx_module_type}_MODULES \ + $ngx_module_name\" + + NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_module_srcs" + + if test -n "$ngx_module_incs"; then + eval ${ngx_var}_INCS=\"\$${ngx_var}_INCS $ngx_module_incs\" + fi + + if test -n "$ngx_module_deps"; then + NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_module_deps" + fi + + for lib in $ngx_module_libs + do + case $lib in + + PCRE | OPENSSL | MD5 | SHA1 | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP) + eval USE_${lib}=YES + ;; + + *) + CORE_LIBS="$CORE_LIBS $lib" + ;; + + esac + done +fi diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -55,6 +55,45 @@ if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = fi +HTTP_MODULES= +HTTP_DEPS= +HTTP_INCS= + +ngx_module_type=HTTP + +if :; then + ngx_module_name="ngx_http_module \ + ngx_http_core_module \ + ngx_http_log_module \ + ngx_http_upstream_module" + ngx_module_incs="src/http src/http/modules" + ngx_module_deps="src/http/ngx_http.h \ + src/http/ngx_http_request.h \ + src/http/ngx_http_config.h \ + src/http/ngx_http_core_module.h \ + src/http/ngx_http_cache.h \ + src/http/ngx_http_variables.h \ + src/http/ngx_http_script.h \ + src/http/ngx_http_upstream.h \ + src/http/ngx_http_upstream_round_robin.h" + ngx_module_srcs="src/http/ngx_http.c \ + src/http/ngx_http_core_module.c \ + src/http/ngx_http_special_response.c \ + src/http/ngx_http_request.c \ + src/http/ngx_http_parse.c \ + src/http/modules/ngx_http_log_module.c \ + src/http/ngx_http_request_body.c \ + src/http/ngx_http_variables.c \ + src/http/ngx_http_script.c \ + src/http/ngx_http_upstream.c \ + src/http/ngx_http_upstream_round_robin.c" + ngx_module_libs= + ngx_module_link=YES + + . auto/module +fi + + if [ $HTTP != YES ]; then have=NGX_CRYPT . auto/nohave CRYPT_LIB= @@ -117,304 +156,872 @@ fi # ngx_http_not_modified_filter # ngx_http_slice_filter -HTTP_FILTER_MODULES="$HTTP_WRITE_FILTER_MODULE \ - $HTTP_HEADER_FILTER_MODULE \ - $HTTP_CHUNKED_FILTER_MODULE" +ngx_module_type=HTTP_FILTER +HTTP_FILTER_MODULES= + +if :; then + ngx_module_name=ngx_http_write_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/ngx_http_write_filter_module.c + ngx_module_libs= + ngx_module_link=YES + + . auto/module +fi + +if :; then + ngx_module_name=ngx_http_header_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/ngx_http_header_filter_module.c + ngx_module_libs= + ngx_module_link=YES + + . auto/module +fi + +if :; then + ngx_module_name=ngx_http_chunked_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/modules/ngx_http_chunked_filter_module.c + ngx_module_libs= + ngx_module_link=YES + + . auto/module +fi if [ $HTTP_V2 = YES ]; then - HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_V2_FILTER_MODULE" + ngx_module_name=ngx_http_v2_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/v2/ngx_http_v2_filter_module.c + ngx_module_libs= + ngx_module_link=$HTTP_V2 + + . auto/module fi -HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_RANGE_HEADER_FILTER_MODULE" +if :; then + ngx_module_name=ngx_http_range_header_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/modules/ngx_http_range_filter_module.c + ngx_module_libs= + ngx_module_link=YES + + . auto/module +fi if [ $HTTP_GZIP = YES ]; then have=NGX_HTTP_GZIP . auto/have USE_ZLIB=YES - HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GZIP_FILTER_MODULE" - HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS" + + ngx_module_name=ngx_http_gzip_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/modules/ngx_http_gzip_filter_module.c + ngx_module_libs= + ngx_module_link=$HTTP_GZIP + + . auto/module fi if [ $HTTP_POSTPONE = YES ]; then - HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_POSTPONE_FILTER_MODULE" - HTTP_SRCS="$HTTP_SRCS $HTTP_POSTPONE_FILTER_SRCS" + ngx_module_name=ngx_http_postpone_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/ngx_http_postpone_filter_module.c + ngx_module_libs= + ngx_module_link=$HTTP_POSTPONE + + . auto/module fi if [ $HTTP_SSI = YES ]; then have=NGX_HTTP_SSI . auto/have - HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSI_FILTER_MODULE" - HTTP_DEPS="$HTTP_DEPS $HTTP_SSI_DEPS" - HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS" + + ngx_module_name=ngx_http_ssi_filter_module + ngx_module_incs= + ngx_module_deps=src/http/modules/ngx_http_ssi_filter_module.h + ngx_module_srcs=src/http/modules/ngx_http_ssi_filter_module.c + ngx_module_libs= + ngx_module_link=$HTTP_SSI + + . auto/module fi if [ $HTTP_CHARSET = YES ]; then - HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE" - HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS" + ngx_module_name=ngx_http_charset_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/modules/ngx_http_charset_filter_module.c + ngx_module_libs= + ngx_module_link=$HTTP_CHARSET + + . auto/module fi if [ $HTTP_XSLT = YES ]; then - USE_LIBXSLT=YES - HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_XSLT_FILTER_MODULE" - HTTP_SRCS="$HTTP_SRCS $HTTP_XSLT_SRCS" + ngx_module_name=ngx_http_xslt_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/modules/ngx_http_xslt_filter_module.c + ngx_module_libs=LIBXSLT + ngx_module_link=$HTTP_XSLT + + . auto/module fi if [ $HTTP_IMAGE_FILTER = YES ]; then - USE_LIBGD=YES - HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_IMAGE_FILTER_MODULE" - HTTP_SRCS="$HTTP_SRCS $HTTP_IMAGE_SRCS" + ngx_module_name=ngx_http_image_filter_module + ngx_module_incs= + ngx_module_deps= + ngx_module_srcs=src/http/modules/ngx_http_image_filter_module.c + ngx_module_libs=LIBGD + ngx_module_link=$HTTP_IMAGE_FILTER From mdounin at mdounin.ru Thu Feb 4 18:40:42 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 04 Feb 2016 18:40:42 +0000 Subject: [nginx] Dynamic modules. Message-ID: details: http://hg.nginx.org/nginx/rev/85dea406e18f branches: changeset: 6383:85dea406e18f user: Maxim Dounin date: Thu Feb 04 20:25:29 2016 +0300 description: Dynamic modules. The auto/module script is extended to understand ngx_module_link=DYNAMIC. When set, it links the module as a shared object rather than statically into nginx binary. The module can later be loaded using the "load_module" directive. New auto/module parameter ngx_module_order allows to define module loading order in complex cases. By default the order is set based on ngx_module_type. 3rd party modules can be compiled dynamically using the --add-dynamic-module configure option, which will preset ngx_module_link to "DYNAMIC" before calling the module config script. Win32 support is rudimentary, and only works when using MinGW gcc (which is able to handle exports/imports automatically). In collaboration with Ruslan Ermilov. diffstat: auto/cc/conf | 22 +++ auto/cc/msvc | 6 + auto/cc/sunc | 3 + auto/init | 1 + auto/install | 24 +++ auto/lib/conf | 6 +- auto/lib/geoip/conf | 7 +- auto/lib/libgd/conf | 7 +- auto/lib/libxslt/conf | 13 +- auto/make | 203 ++++++++++++++++++++++++++++++++- auto/module | 53 ++++++++- auto/modules | 127 ++++++++++++++++++- auto/options | 26 ++++- auto/os/darwin | 3 + auto/os/win32 | 5 + auto/summary | 1 + src/core/nginx.c | 109 +++++++++++++++++ src/core/ngx_cycle.c | 5 +- src/core/ngx_cycle.h | 2 + src/core/ngx_module.c | 308 +++++++++++++++++++++++++++++++++++++++++++++++++- src/core/ngx_module.h | 239 ++++++++++++++++++++++++++++++++++++++- 21 files changed, 1136 insertions(+), 34 deletions(-) diffs (truncated from 1720 to 300 lines): diff --git a/auto/cc/conf b/auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -5,12 +5,17 @@ LINK="\$(CC)" +MAIN_LINK= +MODULE_LINK="-shared" + ngx_include_opt="-I " ngx_compile_opt="-c" +ngx_pic_opt="-fPIC" ngx_objout="-o " ngx_binout="-o " ngx_objext="o" ngx_binext= +ngx_modext=".so" ngx_long_start= ngx_long_end= @@ -45,6 +50,9 @@ if test -n "$CFLAGS"; then sunc) + MAIN_LINK= + MODULE_LINK="-G" + case "$NGX_MACHINE" in i86pc) @@ -156,6 +164,20 @@ if [ "$NGX_PLATFORM" != win32 ]; then fi + ngx_feature="-Wl,-E switch" + ngx_feature_name= + ngx_feature_run=no + ngx_feature_incs= + ngx_feature_path= + ngx_feature_libs=-Wl,-E + ngx_feature_test= + . auto/feature + + if [ $ngx_found = yes ]; then + MAIN_LINK="-Wl,-E" + fi + + ngx_feature="gcc builtin atomic operations" ngx_feature_name=NGX_HAVE_GCC_ATOMIC ngx_feature_run=yes diff --git a/auto/cc/msvc b/auto/cc/msvc --- a/auto/cc/msvc +++ b/auto/cc/msvc @@ -118,6 +118,12 @@ NGX_RCC="rc -fo$NGX_RES \$(CORE_INCS) $N CORE_LINK="$NGX_RES $CORE_LINK" +# dynamic modules +#MAIN_LINK="-link -def:$NGX_OBJS/nginx.def" +#MODULE_LINK="-LD $NGX_OBJS/nginx.lib" + + +ngx_pic_opt= ngx_objout="-Fo" ngx_binout="-Fe" ngx_objext="obj" diff --git a/auto/cc/sunc b/auto/cc/sunc --- a/auto/cc/sunc +++ b/auto/cc/sunc @@ -57,6 +57,9 @@ case "$NGX_MACHINE" in esac +MAIN_LINK= +MODULE_LINK="-G" + # optimizations diff --git a/auto/init b/auto/init --- a/auto/init +++ b/auto/init @@ -5,6 +5,7 @@ NGX_MAKEFILE=$NGX_OBJS/Makefile NGX_MODULES_C=$NGX_OBJS/ngx_modules.c +NGX_MODULES= NGX_AUTO_HEADERS_H=$NGX_OBJS/ngx_auto_headers.h NGX_AUTO_CONFIG_H=$NGX_OBJS/ngx_auto_config.h diff --git a/auto/install b/auto/install --- a/auto/install +++ b/auto/install @@ -26,6 +26,18 @@ case ".$NGX_SBIN_PATH" in esac +case ".$NGX_MODULES_PATH" in + ./*) + ;; + + *) + NGX_MODULES_PATH=$NGX_PREFIX/$NGX_MODULES_PATH + ;; +esac + +NGX_MODULES_PATH=`dirname $NGX_MODULES_PATH/.` + + case ".$NGX_CONF_PATH" in ./*) ;; @@ -158,12 +170,24 @@ END fi +if test -n "$NGX_MODULES"; then + cat << END >> $NGX_MAKEFILE + + test -d '\$(DESTDIR)$NGX_MODULES_PATH' \ + || mkdir -p '\$(DESTDIR)$NGX_MODULES_PATH' + cp $NGX_MODULES '\$(DESTDIR)$NGX_MODULES_PATH' +END + +fi + + # create Makefile cat << END >> Makefile build: \$(MAKE) -f $NGX_MAKEFILE + \$(MAKE) -f $NGX_MAKEFILE modules \$(MAKE) -f $NGX_MAKEFILE manpage install: diff --git a/auto/lib/conf b/auto/lib/conf --- a/auto/lib/conf +++ b/auto/lib/conf @@ -58,11 +58,11 @@ if [ $USE_ZLIB = YES ]; then . auto/lib/zlib/conf fi -if [ $USE_LIBXSLT = YES ]; then +if [ $USE_LIBXSLT != NO ]; then . auto/lib/libxslt/conf fi -if [ $USE_LIBGD = YES ]; then +if [ $USE_LIBGD != NO ]; then . auto/lib/libgd/conf fi @@ -70,7 +70,7 @@ if [ $USE_PERL = YES ]; then . auto/lib/perl/conf fi -if [ $HTTP_GEOIP = YES ]; then +if [ $USE_GEOIP != NO ]; then . auto/lib/geoip/conf fi diff --git a/auto/lib/geoip/conf b/auto/lib/geoip/conf --- a/auto/lib/geoip/conf +++ b/auto/lib/geoip/conf @@ -67,7 +67,12 @@ fi if [ $ngx_found = yes ]; then CORE_INCS="$CORE_INCS $ngx_feature_path" - CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + + if [ $USE_GEOIP = YES ]; then + CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + fi + + NGX_LIB_GEOIP=$ngx_feature_libs if [ $NGX_IPV6 = YES ]; then ngx_feature="GeoIP IPv6 support" diff --git a/auto/lib/libgd/conf b/auto/lib/libgd/conf --- a/auto/lib/libgd/conf +++ b/auto/lib/libgd/conf @@ -67,7 +67,12 @@ fi if [ $ngx_found = yes ]; then CORE_INCS="$CORE_INCS $ngx_feature_path" - CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + + if [ $USE_LIBGD = YES ]; then + CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + fi + + NGX_LIB_LIBGD=$ngx_feature_libs else diff --git a/auto/lib/libxslt/conf b/auto/lib/libxslt/conf --- a/auto/lib/libxslt/conf +++ b/auto/lib/libxslt/conf @@ -76,7 +76,12 @@ fi if [ $ngx_found = yes ]; then CORE_INCS="$CORE_INCS $ngx_feature_path" - CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + + if [ $USE_LIBXSLT = YES ]; then + CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + fi + + NGX_LIB_LIBXSLT=$ngx_feature_libs else @@ -152,5 +157,9 @@ fi if [ $ngx_found = yes ]; then - CORE_LIBS="$CORE_LIBS -lexslt" + if [ $USE_LIBXSLT = YES ]; then + CORE_LIBS="$CORE_LIBS -lexslt" + fi + + NGX_LIB_LIBXSLT="$NGX_LIB_LIBXSLT -lexslt" fi diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -98,9 +98,11 @@ fi # the mail dependencies and include paths -if [ $MAIL = YES ]; then +if [ $MAIL != NO ]; then - ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS" + if [ $MAIL = YES ]; then + ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS" + fi ngx_deps=`echo $MAIL_DEPS \ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \ @@ -124,9 +126,11 @@ fi # the stream dependencies and include paths -if [ $STREAM = YES ]; then +if [ $STREAM != NO ]; then - ngx_all_srcs="$ngx_all_srcs $STREAM_SRCS" + if [ $STREAM = YES ]; then + ngx_all_srcs="$ngx_all_srcs $STREAM_SRCS" + fi ngx_deps=`echo $STREAM_DEPS \ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \ @@ -204,6 +208,7 @@ ngx_objs=`echo $ngx_all_objs $ngx_module | sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \ -e "s/\//$ngx_regex_dirsep/g"` +ngx_libs= if test -n "$NGX_LD_OPT$CORE_LIBS"; then ngx_libs=`echo $NGX_LD_OPT $CORE_LIBS \ | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"` @@ -212,13 +217,18 @@ fi ngx_link=${CORE_LINK:+`echo $CORE_LINK \ | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`} +ngx_main_link=${MAIN_LINK:+`echo $MAIN_LINK \ + | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`} + cat << END >> $NGX_MAKEFILE $NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer - \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link + \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link $ngx_rcc ${ngx_long_end} + +modules: END @@ -472,3 +482,186 @@ if test -n "$NGX_PCH"; then END fi + + +# dynamic modules + +if test -n "$NGX_PCH"; then + ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" +else + ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) \$(ALL_INCS)" +fi + From sam at surround.io Thu Feb 4 21:38:48 2016 From: sam at surround.io (Sam McKelvie) Date: Thu, 4 Feb 2016 13:38:48 -0800 Subject: Proposed changeset to fix client cert from ngx_ssl_get_certificate passed as HTTP header value In-Reply-To: <20160204182928.GF70403@mdounin.ru> References: <20160204182928.GF70403@mdounin.ru> Message-ID: I think it is your call if you want to make a breaking change to $ssl_client_cert to URL encode it; I'd be happy to submit the changeset if you would approve that, but I personally don't feel comfortable breaking any existing applications that parse/decode the certificate. So my suggestion now is to define a new $ssl_client_cert_url_encoded variable that is the URL-encoded form of the raw PEM certificate. With your approval I will submit a changeset for that... Sam On Thu, Feb 4, 2016 at 10:29 AM, Maxim Dounin wrote: > Hello! > > On Thu, Feb 04, 2016 at 09:17:31AM -0800, Sam McKelvie wrote: > >> > Hello! >> > >> > On Wed, Feb 03, 2016 at 03:38:13PM -0800, Sam McKelvie wrote: >> > >> >> The ngx_ssl_get_certificate() changes ?\n? to ?\n\t? in the returned PEM string in an effort to make >> >> the string usable as an HTTP header value with $ssl_client_cert. However, bare ?\n? (without a preceding ?\r?) is passed >> >> along as ?\n\t". This causes some HTTP servers (including node/express) to hang up. This changeset >> >> fixes the problem by replacing occurrences of ?\n? that have no preceding ?\r? with "\r\n\t". >> >> >> >> Tested with node.js/express and nginx-tests. >> >> >> >> I should note that a similar solution was proposed at https://forum.nginx.org/read.php?29,249804,249833 , but the thread never went anywhere. >> >> This solution is slightly more paranoid with edge cases and does not insert extra ?\r? characters if they are already present. >> > >> > IMHO, header line folding is wrong enough to don't bother with >> > trying to fix this. It doesn't work in way too many cases >> > including with nginx itself, and it is deprecated by RFC7230. >> > >> > Much better approach would be to switch to something different - >> > may be just properly urlencoded $ssl_client_raw_cert, or plain >> > base64 without any newlines, or whatever. >> > >> I tend to agree. However, nix_ssl_get_certificate() is already folding >> the certificate for HTTP headers by inserting '\t' at the beginning of >> each line, so that seems to be its primary purpose. I can?t change >> that function to return anything that is not itself a valid PEM >> certificate, or it would certainly break any existing applications >> that parse the results. So unless you think it is OK to tweak it to >> insert '\r' as well, I think you are saying this function is just >> permanently unusable for the purposes of passing a certificate in a >> header. > > Current implementation is usable where it is currently used. Most > servers happen to parse "\n" without "\r" just fine. RFC2616 > explicitly recommends applications to accept bare LF, > http://tools.ietf.org/html/rfc2616#section-19.3: > > The line terminator for message-header fields is the sequence CRLF. > However, we recommend that applications, when parsing such headers, > recognize a single LF as a line terminator and ignore the leading CR. > > On the other hand, any changes, even minor ones like adding "\r", > may break existing applications who use $ssl_client_cert. And if > we are goint to introduce changes - it's better to change it > something more useable than header folding. > >> Would you be more amenable to defining a new "$ssl_base64_client_cert" >> or ?$ssl_escaped_client_cert? variable that is a properly encoded PEM >> string? Would you prefer base64 (which would greatly increase the >> size) or a quoted-string for with backslashes to escape control >> characters? I would be willing to submit such a changeset? > > For sure base64-encoded PEM is not something we want, that would > be double base64 encoding and makes no sense. Base64-encoded DER > (== PEM without header/footer/newlines) may be an option. > > I tend to think that we want to use URI escaping here. We already > do this in mail for Auth-SSL-Cert header, with minimal escaping. > As we don't know context for the variable - it probably would be a > better option to escape it as an URI component. > > Tricky part here is to understand what we are going to do with the > $ssl_client_cert variable. I don't like the idea of preserving it > in "PEM with tab added for header folding" forever. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From ru at nginx.com Fri Feb 5 11:03:29 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 05 Feb 2016 11:03:29 +0000 Subject: [nginx] Dynamic modules: fixed a copy-n-paste error. Message-ID: details: http://hg.nginx.org/nginx/rev/e0d7c2f71851 branches: changeset: 6384:e0d7c2f71851 user: Ruslan Ermilov date: Fri Feb 05 14:02:54 2016 +0300 description: Dynamic modules: fixed a copy-n-paste error. diffstat: auto/modules | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 85dea406e18f -r e0d7c2f71851 auto/modules --- a/auto/modules Thu Feb 04 20:25:29 2016 +0300 +++ b/auto/modules Fri Feb 05 14:02:54 2016 +0300 @@ -331,7 +331,7 @@ if [ $HTTP_ADDITION = YES ]; then ngx_module_deps= ngx_module_srcs=src/http/modules/ngx_http_addition_filter_module.c ngx_module_libs= - ngx_module_link=$HTTP_SUB + ngx_module_link=$HTTP_ADDITION . auto/module fi From dk at syse.no Fri Feb 5 11:30:17 2016 From: dk at syse.no (Daniel K.) Date: Fri, 5 Feb 2016 11:30:17 +0000 Subject: [nginx] Dynamic modules. In-Reply-To: References: Message-ID: <56B487C9.5050002@syse.no> On 02/04/2016 06:40 PM, Maxim Dounin wrote: > Dynamic modules. > > diffstat: > > [...] > 21 files changed, 1136 insertions(+), 34 deletions(-) Thanks for posting your work on dynamic modules, but the following > diffs (truncated from 1720 to 300 lines): makes this and other mail in the series a bit useless. Could you somehow avoid the truncation in future postings? Daniel K. From luky-37 at hotmail.com Fri Feb 5 11:44:12 2016 From: luky-37 at hotmail.com (Lukas Tribus) Date: Fri, 5 Feb 2016 12:44:12 +0100 Subject: [nginx] Dynamic modules. In-Reply-To: <56B487C9.5050002@syse.no> References: , <56B487C9.5050002@syse.no> Message-ID: >> diffs (truncated from 1720 to 300 lines): > > makes this and other mail in the series a bit useless. You are supposed to checkout the mercury repository,?not apply committed patches from the dev list manually if they are?committed anyway. Just clone it: hg clone http://hg.nginx.org/nginx and refresh it: $ cd nginx ~/nginx$ hg pull From mdounin at mdounin.ru Fri Feb 5 12:52:03 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 5 Feb 2016 15:52:03 +0300 Subject: [nginx] Dynamic modules. In-Reply-To: <56B487C9.5050002@syse.no> References: <56B487C9.5050002@syse.no> Message-ID: <20160205125202.GH70403@mdounin.ru> Hello! On Fri, Feb 05, 2016 at 11:30:17AM +0000, Daniel K. wrote: > On 02/04/2016 06:40 PM, Maxim Dounin wrote: > > Dynamic modules. > > > > diffstat: > > > > [...] > > 21 files changed, 1136 insertions(+), 34 deletions(-) > > Thanks for posting your work on dynamic modules, but the following > > > diffs (truncated from 1720 to 300 lines): > > makes this and other mail in the series a bit useless. > > Could you somehow avoid the truncation in future postings? The details: http://hg.nginx.org/nginx/rev/85dea406e18f line at the top of the message contains link to the full changeset if you want to read all the details. -- Maxim Dounin http://nginx.org/ From dk at syse.no Fri Feb 5 13:16:51 2016 From: dk at syse.no (Daniel K.) Date: Fri, 5 Feb 2016 13:16:51 +0000 Subject: [nginx] Dynamic modules. In-Reply-To: <20160205125202.GH70403@mdounin.ru> References: <56B487C9.5050002@syse.no> <20160205125202.GH70403@mdounin.ru> Message-ID: <56B4A0C3.9040602@syse.no> On 02/05/2016 12:52 PM, Maxim Dounin wrote: > The > > details: http://hg.nginx.org/nginx/rev/85dea406e18f > > line at the top of the message contains link to the full changeset > if you want to read all the details. I know, but why send out anything other than the metadata if the diff may be truncated? I'm pretty new to this list, maybe all of you are just used to it being this way. Oh, well. Daniel K. From mdounin at mdounin.ru Fri Feb 5 14:33:33 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 5 Feb 2016 17:33:33 +0300 Subject: [nginx] Dynamic modules. In-Reply-To: <56B4A0C3.9040602@syse.no> References: <56B487C9.5050002@syse.no> <20160205125202.GH70403@mdounin.ru> <56B4A0C3.9040602@syse.no> Message-ID: <20160205143333.GO70403@mdounin.ru> Hello! On Fri, Feb 05, 2016 at 01:16:51PM +0000, Daniel K. wrote: > On 02/05/2016 12:52 PM, Maxim Dounin wrote: > > The > > > > details: http://hg.nginx.org/nginx/rev/85dea406e18f > > > > line at the top of the message contains link to the full changeset > > if you want to read all the details. > > I know, but why send out anything other than the metadata if the diff > may be truncated? Because 1) in most cases diffs are not truncated as most changes are small enough, and 2) even when truncated, diffs show some useful information for readers, in most cases enough to understand if you want to dig into details or not. What probably can be adjusted is truncation limit, as 300 may be a bit too low. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Fri Feb 5 15:58:12 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 5 Feb 2016 18:58:12 +0300 Subject: Proposed changeset to fix client cert from ngx_ssl_get_certificate passed as HTTP header value In-Reply-To: References: <20160204182928.GF70403@mdounin.ru> Message-ID: <20160205155811.GP70403@mdounin.ru> Hello! On Thu, Feb 04, 2016 at 01:38:48PM -0800, Sam McKelvie wrote: > I think it is your call if you want to make a breaking change to > $ssl_client_cert to URL encode it; I'd be happy to submit the > changeset if you would approve that, but I personally don't feel > comfortable breaking any existing applications that parse/decode the > certificate. No, certainly not something I want to be done. > So my suggestion now is to define a new $ssl_client_cert_url_encoded > variable that is the URL-encoded form of the raw PEM certificate. With > your approval I will submit a changeset for that... Yes, adding a variable with an URL-escaped versions looks like a way to go. I disagree with the name you suggest though, I think that something like $ssl_client_escaped_cert would be more in line with $ssl_client_cert and $ssl_client_raw_cert variables we currently have and the ngx_escape_uri() function nginx uses internally. Some more background. As of now we have: - $ssl_client_raw_cert - client cert in PEM format - $ssl_client_cert - client cert in PEM format with \t added At some distant point in the future we probably want to have: - $ssl_client_cert - client cert in PEM format - a way to urlescape() things, see https://trac.nginx.org/nginx/ticket/52 At this point, an escaped version of the client cert will be available as something like ${urlescape($ssl_client_cert)}. All uses of client cert with tabs are expected to disappear. There are a couple of problems though: - there are existing uses of $ssl_client_cert and $ssl_client_raw_cert, breaking them would be bad; - we don't have urlescape() function in configs, and probably won't have it in a near future. So we have to figure out some migration plan, e.g.: - introduce $ssl_client_escaped_cert, with urlescaped PEM cert; - introduce $ssl_client_tabbed_cert as an alias to $ssl_client_cert (with PEM cert with tabs); - change $ssl_client_cert back to be raw cert (preserving $ssl_client_raw_cert as a deprecated alias for some time); - do something with $ssl_client_tabbed_cert at some point, not sure; - once urlescape() functionality is added, deprecate $ssl_client_escaped_cert, suggesting to use urlescape($ssl_client_cert) instead. Not sure if it's an optimal plan and if we are actually going to follow it, but introducing $ssl_client_escaped_cert looks like a more or less obvious 1st step, at least if we don't expect urlescape() to appear in the near future. -- Maxim Dounin http://nginx.org/ From vbart at nginx.com Sat Feb 6 18:10:24 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Sat, 06 Feb 2016 18:10:24 +0000 Subject: [nginx] Dynamic modules: added dlsym() to configure test. Message-ID: details: http://hg.nginx.org/nginx/rev/3577c021f21e branches: changeset: 6385:3577c021f21e user: Valentin Bartenev date: Fri Feb 05 21:48:25 2016 +0300 description: Dynamic modules: added dlsym() to configure test. It appears that AddressSanitizer in GCC 5 intercepts dlopen() and dlclose() but not dlsym(). diffstat: auto/unix | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r e0d7c2f71851 -r 3577c021f21e auto/unix --- a/auto/unix Fri Feb 05 14:02:54 2016 +0300 +++ b/auto/unix Fri Feb 05 21:48:25 2016 +0300 @@ -260,7 +260,7 @@ ngx_feature_run=no ngx_feature_incs="#include " ngx_feature_path= ngx_feature_libs= -ngx_feature_test="dlopen(NULL, 0)" +ngx_feature_test="dlopen(NULL, 0); dlsym(NULL, NULL)" . auto/feature From whissi at whissi.de Sat Feb 6 20:53:31 2016 From: whissi at whissi.de (Thomas D.) Date: Sat, 06 Feb 2016 21:53:31 +0100 Subject: [PATCH] Configure: Add option to build without http_slice module Message-ID: <5215fb0cdfd367c8cd4a.1454792011@vm-gentoo-x64.intern.deutschmann.biz> # HG changeset patch # User Thomas D. # Date 1454790517 -3600 # Sat Feb 06 21:28:37 2016 +0100 # Node ID 5215fb0cdfd367c8cd4ab1c56a7ef5e19005e8b9 # Parent 3577c021f21eb4de6d09c1d624ba77ee9ee1eb6d Configure: Add option to build without http_slice module In Gentoo we explicitly enable and disable modules we use or don't use. The newly added HTTP slice module was added without an option to disable the module resulting in an error like > ./configure: error: invalid option "--without-http_slice_module" This commit adds an option "--without-http_slice_module" to allow users to explicitly disable the module like others. Bug: https://bugs.gentoo.org/show_bug.cgi?id=574020 diff -r 3577c021f21e -r 5215fb0cdfd3 auto/options --- a/auto/options Fri Feb 05 21:48:25 2016 +0300 +++ b/auto/options Sat Feb 06 21:28:37 2016 +0100 @@ -243,6 +243,7 @@ --without-http_charset_module) HTTP_CHARSET=NO ;; --without-http_gzip_module) HTTP_GZIP=NO ;; + --without-http_slice_module) HTTP_SLICE=NO ;; --without-http_ssi_module) HTTP_SSI=NO ;; --without-http_userid_module) HTTP_USERID=NO ;; --without-http_access_module) HTTP_ACCESS=NO ;; @@ -421,6 +422,7 @@ --without-http_charset_module disable ngx_http_charset_module --without-http_gzip_module disable ngx_http_gzip_module + --without-http_slice_module disable ngx_http_slice_module --without-http_ssi_module disable ngx_http_ssi_module --without-http_userid_module disable ngx_http_userid_module --without-http_access_module disable ngx_http_access_module From pluknet at nginx.com Sat Feb 6 21:40:43 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Sun, 7 Feb 2016 00:40:43 +0300 Subject: [PATCH] Configure: Add option to build without http_slice module In-Reply-To: <5215fb0cdfd367c8cd4a.1454792011@vm-gentoo-x64.intern.deutschmann.biz> References: <5215fb0cdfd367c8cd4a.1454792011@vm-gentoo-x64.intern.deutschmann.biz> Message-ID: <5004215B-2089-406C-BD51-EC880B12E524@nginx.com> On Feb 6, 2016, at 11:53 PM, Thomas D. wrote: > # HG changeset patch > # User Thomas D. > # Date 1454790517 -3600 > # Sat Feb 06 21:28:37 2016 +0100 > # Node ID 5215fb0cdfd367c8cd4ab1c56a7ef5e19005e8b9 > # Parent 3577c021f21eb4de6d09c1d624ba77ee9ee1eb6d > Configure: Add option to build without http_slice module > > In Gentoo we explicitly enable and disable modules we use or don't use. > > The newly added HTTP slice module was added without an option to disable > the module resulting in an error like > >> ./configure: error: invalid option "--without-http_slice_module" The module is opt-in rather than opt-out. See for more details: http://nginx.org/en/docs/http/ngx_http_slice_module.html -- Sergey Kandaurov From pavel2000 at ngs.ru Sun Feb 7 09:32:42 2016 From: pavel2000 at ngs.ru (Pavel V. Rochnyack) Date: Sun, 07 Feb 2016 15:32:42 +0600 Subject: [PATCH] Limit req, Limit conn: The "off" parameter of the 'limit_conn' and 'limit_req' directives Message-ID: # HG changeset patch # User Pavel V. Rochnyack # Date 1454835814 -21600 # Node ID f7caa68ea80358a035ab766bdb62676522ec529f # Parent 3577c021f21eb4de6d09c1d624ba77ee9ee1eb6d Limit req, Limit conn: The "off" parameter of the 'limit_conn' and 'limit_req' directives. Added support for inherited "limit_conn" and "limit_req" directives disable. diff -r 3577c021f21e -r f7caa68ea803 src/http/modules/ngx_http_limit_conn_module.c --- a/src/http/modules/ngx_http_limit_conn_module.c Fri Feb 05 21:48:25 2016 +0300 +++ b/src/http/modules/ngx_http_limit_conn_module.c Sun Feb 07 15:03:34 2016 +0600 @@ -40,6 +40,7 @@ ngx_array_t limits; ngx_uint_t log_level; ngx_uint_t status_code; + ngx_uint_t off; /* unsigned off:1 */ } ngx_http_limit_conn_conf_t; @@ -82,7 +83,7 @@ NULL }, { ngx_string("limit_conn"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, ngx_http_limit_conn, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -160,6 +161,10 @@ lccf = ngx_http_get_module_loc_conf(r, ngx_http_limit_conn_module); limits = lccf->limits.elts; + if (lccf->off) { + return NGX_DECLINED; + } + for (i = 0; i < lccf->limits.nelts; i++) { ctx = limits[i].shm_zone->data; @@ -466,6 +471,7 @@ conf->log_level = NGX_CONF_UNSET_UINT; conf->status_code = NGX_CONF_UNSET_UINT; + conf->off = NGX_CONF_UNSET_UINT; return conf; } @@ -478,6 +484,7 @@ ngx_http_limit_conn_conf_t *conf = child; if (conf->limits.elts == NULL) { + ngx_conf_merge_uint_value(conf->off, prev->off, 0); conf->limits = prev->limits; } @@ -603,6 +610,13 @@ value = cf->args->elts; + lccf->off = 0; + + if (ngx_strcmp(value[1].data, "off") == 0 && cf->args->nelts == 2) { + lccf->off = 1; + return NGX_CONF_OK; + } + shm_zone = ngx_shared_memory_add(cf, &value[1], 0, &ngx_http_limit_conn_module); if (shm_zone == NULL) { diff -r 3577c021f21e -r f7caa68ea803 src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c Fri Feb 05 21:48:25 2016 +0300 +++ b/src/http/modules/ngx_http_limit_req_module.c Sun Feb 07 15:03:34 2016 +0600 @@ -53,6 +53,7 @@ ngx_uint_t limit_log_level; ngx_uint_t delay_log_level; ngx_uint_t status_code; + ngx_uint_t off; /* unsigned off:1 */ } ngx_http_limit_req_conf_t; @@ -172,6 +173,10 @@ lrcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_req_module); limits = lrcf->limits.elts; + if (lrcf->off) { + return NGX_DECLINED; + } + excess = 0; rc = NGX_DECLINED; @@ -698,6 +703,7 @@ conf->limit_log_level = NGX_CONF_UNSET_UINT; conf->status_code = NGX_CONF_UNSET_UINT; + conf->off = NGX_CONF_UNSET_UINT; return conf; } @@ -710,6 +716,7 @@ ngx_http_limit_req_conf_t *conf = child; if (conf->limits.elts == NULL) { + ngx_conf_merge_uint_value(conf->off, prev->off, 0); conf->limits = prev->limits; } @@ -870,6 +877,19 @@ value = cf->args->elts; + lrcf->off = 0; + + if (ngx_strcmp(value[1].data, "off") == 0) { + lrcf->off = 1; + if (cf->args->nelts == 2) { + return NGX_CONF_OK; + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } + shm_zone = NULL; burst = 0; nodelay = 0; From whissi at whissi.de Sun Feb 7 10:59:07 2016 From: whissi at whissi.de (Thomas D.) Date: Sun, 7 Feb 2016 11:59:07 +0100 Subject: [PATCH] Configure: Add option to build without http_slice module In-Reply-To: <5004215B-2089-406C-BD51-EC880B12E524@nginx.com> References: <5215fb0cdfd367c8cd4a.1454792011@vm-gentoo-x64.intern.deutschmann.biz> <5004215B-2089-406C-BD51-EC880B12E524@nginx.com> Message-ID: <56B7237B.3080705@whissi.de> Hi, Sergey Kandaurov wrote: > The module is opt-in rather than opt-out. Uhm yes, please ignore my patch: I forgot that we were already handling opt-in modules. We just put "slice" in the wrong category. Sorry for wasting your time. -Thomas From mdounin at mdounin.ru Sun Feb 7 16:40:41 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sun, 7 Feb 2016 19:40:41 +0300 Subject: [PATCH] Limit req, Limit conn: The "off" parameter of the 'limit_conn' and 'limit_req' directives In-Reply-To: References: Message-ID: <20160207164040.GW70403@mdounin.ru> Hello! On Sun, Feb 07, 2016 at 03:32:42PM +0600, Pavel V. Rochnyack wrote: > # HG changeset patch > # User Pavel V. Rochnyack > # Date 1454835814 -21600 > # Node ID f7caa68ea80358a035ab766bdb62676522ec529f > # Parent 3577c021f21eb4de6d09c1d624ba77ee9ee1eb6d > Limit req, Limit conn: The "off" parameter of the 'limit_conn' and 'limit_req' directives. > > Added support for inherited "limit_conn" and "limit_req" directives disable. Please re-read http://nginx.org/en/docs/contributing_changes.html. In particular: : maximum text width is 80 characters ... : The commit message should have a single-line synopsis followed : by verbose description after an empty line. It is desirable that : the first line is no longer than 67 symbols. In this particular case I would also recommend to split the patch into two separate patches: one for limit req, and another one for limit conn. > diff -r 3577c021f21e -r f7caa68ea803 src/http/modules/ngx_http_limit_conn_module.c > --- a/src/http/modules/ngx_http_limit_conn_module.c Fri Feb 05 21:48:25 2016 +0300 > +++ b/src/http/modules/ngx_http_limit_conn_module.c Sun Feb 07 15:03:34 2016 +0600 > @@ -40,6 +40,7 @@ Please add [diff] showfunc=1 to your ~/.hgrc file, this generally simplifies review process. > ngx_array_t limits; > ngx_uint_t log_level; > ngx_uint_t status_code; > + ngx_uint_t off; /* unsigned off:1 */ > } ngx_http_limit_conn_conf_t; Indentation of the "/* unsigned off:1 */" looks wrong. > > > @@ -82,7 +83,7 @@ > NULL }, > > { ngx_string("limit_conn"), > - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, > + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, > ngx_http_limit_conn, > NGX_HTTP_LOC_CONF_OFFSET, > 0, > @@ -160,6 +161,10 @@ > lccf = ngx_http_get_module_loc_conf(r, ngx_http_limit_conn_module); > limits = lccf->limits.elts; > > + if (lccf->off) { > + return NGX_DECLINED; > + } > + > for (i = 0; i < lccf->limits.nelts; i++) { > ctx = limits[i].shm_zone->data; > > @@ -466,6 +471,7 @@ > > conf->log_level = NGX_CONF_UNSET_UINT; > conf->status_code = NGX_CONF_UNSET_UINT; > + conf->off = NGX_CONF_UNSET_UINT; > > return conf; > } > @@ -478,6 +484,7 @@ > ngx_http_limit_conn_conf_t *conf = child; > > if (conf->limits.elts == NULL) { > + ngx_conf_merge_uint_value(conf->off, prev->off, 0); > conf->limits = prev->limits; > } > See no reasons why limits from previous level should be meged if "off" is used on the current level. It's just unneeded work, which also add complexity in other places (like a need to check off at runtime, and merge off values from previous levels). Better approach would be to don't inherit limits if "off" is set on the current level. > @@ -603,6 +610,13 @@ > > value = cf->args->elts; > > + lccf->off = 0; > + > + if (ngx_strcmp(value[1].data, "off") == 0 && cf->args->nelts == 2) { > + lccf->off = 1; > + return NGX_CONF_OK; > + } > + > shm_zone = ngx_shared_memory_add(cf, &value[1], 0, > &ngx_http_limit_conn_module); > if (shm_zone == NULL) { This variant of the code doesn't check "off" if additional arguments are used. Limit req's version however does (and complains if number of arguments is incorrect). Reasons for the difference are not clear. With this code something like "limit_conn foo" will try to access value[2] unconditionally, potentially resulting in segmentation fault during configuration parsing. This code silently allows "limit_conn off" to be used multiple times, as well as with other limit_conn directives. This leads to a situation where: limit_conn off; limit_conn foo 10; will not use "limit_conn foo 10" configured without any indication, which looks incorrect and confusing. It should either complain, or use limits configured. > diff -r 3577c021f21e -r f7caa68ea803 src/http/modules/ngx_http_limit_req_module.c > --- a/src/http/modules/ngx_http_limit_req_module.c Fri Feb 05 21:48:25 2016 +0300 > +++ b/src/http/modules/ngx_http_limit_req_module.c Sun Feb 07 15:03:34 2016 +0600 > @@ -53,6 +53,7 @@ > ngx_uint_t limit_log_level; > ngx_uint_t delay_log_level; > ngx_uint_t status_code; > + ngx_uint_t off; /* unsigned off:1 */ > } ngx_http_limit_req_conf_t; > > > @@ -172,6 +173,10 @@ > lrcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_req_module); > limits = lrcf->limits.elts; > > + if (lrcf->off) { > + return NGX_DECLINED; > + } > + > excess = 0; > > rc = NGX_DECLINED; > @@ -698,6 +703,7 @@ > > conf->limit_log_level = NGX_CONF_UNSET_UINT; > conf->status_code = NGX_CONF_UNSET_UINT; > + conf->off = NGX_CONF_UNSET_UINT; > > return conf; > } > @@ -710,6 +716,7 @@ > ngx_http_limit_req_conf_t *conf = child; > > if (conf->limits.elts == NULL) { > + ngx_conf_merge_uint_value(conf->off, prev->off, 0); > conf->limits = prev->limits; > } > > @@ -870,6 +877,19 @@ > > value = cf->args->elts; > > + lrcf->off = 0; > + > + if (ngx_strcmp(value[1].data, "off") == 0) { > + lrcf->off = 1; > + if (cf->args->nelts == 2) { > + return NGX_CONF_OK; > + } > + > + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > + "invalid parameter \"%V\"", &value[2]); > + return NGX_CONF_ERROR; > + } > + > shm_zone = NULL; > burst = 0; > nodelay = 0; See comments for the limit_conn part of the patch, most of them apply here as well. -- Maxim Dounin http://nginx.org/ From agentzh at gmail.com Sun Feb 7 21:02:37 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Sun, 7 Feb 2016 13:02:37 -0800 Subject: Resumable and composable access handlers in the stream subsystem Message-ID: Hi guys! This is just a feature request. I hope that the stream subsystem of NGINX can support access handlers that are both resumable and composable, just like the access phase handlers in the http subsystem. The former means that the access handler can yield (like returning NGX_DONE) and resume later upon new events. This is important when we want to do nonblocking I/O in this context. The latter means that different modules can register their own access handlers without overriding each other, so the user can, for example, combine the access_by_lua* directives of ngx_stream_lua_module and the standard ngx_stream_access_module in the same stream server. What do you think? Best regards, -agentzh From pavel2000 at ngs.ru Mon Feb 8 04:13:48 2016 From: pavel2000 at ngs.ru (Pavel V.) Date: Mon, 8 Feb 2016 10:13:48 +0600 Subject: [PATCH] Limit req, Limit conn: The "off" parameter of the 'limit_conn' and 'limit_req' directives In-Reply-To: <20160207164040.GW70403@mdounin.ru> References: <20160207164040.GW70403@mdounin.ru> Message-ID: <187700758.20160208101348@ngs.ru> Hi, Maxim. Thanks for reviewing my patch. > See no reasons why limits from previous level should be merged if > "off" is used on the current level. It's just unneeded work, > which also add complexity in other places (like a need to check > off at runtime, and merge off values from previous levels). > Better approach would be to don't inherit limits if "off" is set > on the current level. Ok, this part will be reworked. >> @@ -603,6 +610,13 @@ >> >> value = cf->args->elts; >> >> + lccf->off = 0; >> + >> + if (ngx_strcmp(value[1].data, "off") == 0 && cf->args->nelts == 2) { >> + lccf->off = 1; >> + return NGX_CONF_OK; >> + } >> + >> shm_zone = ngx_shared_memory_add(cf, &value[1], 0, >> &ngx_http_limit_conn_module); >> if (shm_zone == NULL) { > This variant of the code doesn't check "off" if additional > arguments are used. Limit req's version however does (and > complains if number of arguments is incorrect). Reasons for the > difference are not clear. These directives has different syntax at the moment. Directive 'limit_conn' currently allows exactly two arguments and someone can configure Nginx to use zone 'off' by a line ... limit_conn off 42; ... The 'limit_req' directive expects prefix 'zone=' and there is no way to use keyword 'off' as a standalone argument. So, the reason for the difference is backward compatibility with existing configurations. Should we care about this or not? > With this code something like "limit_conn foo" will try to access > value[2] unconditionally, potentially resulting in segmentation > fault during configuration parsing. I has not considered such variant. Thank you for catching this. > This code silently allows "limit_conn off" to be used multiple > times, as well as with other limit_conn directives. This leads to > a situation where: > limit_conn off; > limit_conn foo 10; > will not use "limit_conn foo 10" configured without any > indication, which looks incorrect and confusing. It should either > complain, or use limits configured. I used http_log_module as a guide for such behaviour. It has directive "access_log" with similar syntax "access_log off;" and it does not complains when other directives specified with 'access_log off'. Why this should be handled in the other way here? -- Regards, Pavel mailto:pavel2000 at ngs.ru From mdounin at mdounin.ru Mon Feb 8 14:36:40 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 8 Feb 2016 17:36:40 +0300 Subject: [PATCH] Limit req, Limit conn: The "off" parameter of the 'limit_conn' and 'limit_req' directives In-Reply-To: <187700758.20160208101348@ngs.ru> References: <20160207164040.GW70403@mdounin.ru> <187700758.20160208101348@ngs.ru> Message-ID: <20160208143639.GX70403@mdounin.ru> Hello! On Mon, Feb 08, 2016 at 10:13:48AM +0600, Pavel V. wrote: [...] > > This variant of the code doesn't check "off" if additional > > arguments are used. Limit req's version however does (and > > complains if number of arguments is incorrect). Reasons for the > > difference are not clear. > > These directives has different syntax at the moment. Directive 'limit_conn' > currently allows exactly two arguments and someone can configure Nginx to use > zone 'off' by a line > > ... > limit_conn off 42; > ... > > The 'limit_req' directive expects prefix 'zone=' and there is no way to use > keyword 'off' as a standalone argument. > > So, the reason for the difference is backward compatibility with existing > configurations. Should we care about this or not? I don't think that supporting "off" as a name of a zone worth the effort. Moreover, it's likely to confuse users if supported. [...] > > This code silently allows "limit_conn off" to be used multiple > > times, as well as with other limit_conn directives. This leads to > > a situation where: > > > limit_conn off; > > limit_conn foo 10; > > > will not use "limit_conn foo 10" configured without any > > indication, which looks incorrect and confusing. It should either > > complain, or use limits configured. > > I used http_log_module as a guide for such behaviour. It has directive > "access_log" with similar syntax "access_log off;" and it does not complains > when other directives specified with 'access_log off'. Why this should be > handled in the other way here? Because "access_log off" behaviour is confusing, too? General approach in nginx configs is to don't ignore/redefine somethin defined at the current level, but to complain instead. I don't suggest to change current "access_log off" behaviour as it is likely to cause compatibility problems with existing configurations (or at least we have to introduce warnings first), but we probably don't want to introduce additional places with such confusing behaviour. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Mon Feb 8 16:46:43 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 08 Feb 2016 16:46:43 +0000 Subject: [nginx] Dynamic modules: NGX_STREAM define removed. Message-ID: details: http://hg.nginx.org/nginx/rev/80d594961e68 branches: changeset: 6386:80d594961e68 user: Maxim Dounin date: Mon Feb 08 18:02:04 2016 +0300 description: Dynamic modules: NGX_STREAM define removed. It's not used and contradicts the idea of dynamic loading. diffstat: auto/modules | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diffs (12 lines): diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -973,8 +973,6 @@ if [ $STREAM != NO ]; then STREAM_DEPS= STREAM_INCS= - have=NGX_STREAM . auto/have - ngx_module_type=STREAM ngx_module_libs= ngx_module_link=YES From sreekanth_sk at yahoo.com Tue Feb 9 11:12:55 2016 From: sreekanth_sk at yahoo.com (Sreekanth M) Date: Tue, 9 Feb 2016 11:12:55 +0000 (UTC) Subject: nginx ssl session caching References: <828761722.1400605.1455016375574.JavaMail.yahoo.ref@mail.yahoo.com> Message-ID: <828761722.1400605.1455016375574.JavaMail.yahoo@mail.yahoo.com> Hi, I am doing ssl session caching using the NGINX shared memory cache and getting high response times in load testing. Test setup: clients -------> ?NGINX --------> server Client sends around 200 Requests/sec ?and 50% of requests reuses ssl session. NGINX version is 1.0.10 and OpenSSL version used is?OpenSSL 1.0.1e-fips 11 Feb 2013. Test Results: Test shows that the connect time increases to 200 secs at time t = 700s (refer session_caching.png attachment).?This looks like an issue with OpenSSL framework as there is some delay in processing SSL requests over period of time.? Please note that the connect ?time is just 70 ms when external session caching is OFF (refer no_session_caching.png attachment). Has anyone faced similar issues with OpenSSL + NGINX ?testing ?? Any feed back would be appreciated. Thanks,Sreekanth -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: no_session_caching.png Type: image/png Size: 4125 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: session_caching.png Type: image/png Size: 2813 bytes Desc: not available URL: From mdounin at mdounin.ru Tue Feb 9 14:22:25 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 09 Feb 2016 14:22:25 +0000 Subject: [nginx] nginx-1.9.11-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/fe66cff450a9 branches: changeset: 6387:fe66cff450a9 user: Maxim Dounin date: Tue Feb 09 17:11:56 2016 +0300 description: nginx-1.9.11-RELEASE diffstat: docs/xml/nginx/changes.xml | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) diffs (53 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,49 @@ + + + + +?????? resolver ???????????? TCP. + + +TCP support in resolver. + + + + + +???????????? ??????. + + +dynamic modules. + + + + + +??? ????????????? HTTP/2 +?????????? $request_length ?? ????????? ?????? ?????????? ???????. + + +the $request_length variable did not include size of request headers +when using HTTP/2. + + + + + +? ?????? ngx_http_v2_module. + + +in the ngx_http_v2_module. + + + + + + From mdounin at mdounin.ru Tue Feb 9 14:22:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 09 Feb 2016 14:22:27 +0000 Subject: [nginx] release-1.9.11 tag Message-ID: details: http://hg.nginx.org/nginx/rev/50770821c184 branches: changeset: 6388:50770821c184 user: Maxim Dounin date: Tue Feb 09 17:11:57 2016 +0300 description: release-1.9.11 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -393,3 +393,4 @@ 54117529e40b988590ea2d38aae909b0b191663f 1bdc497c81607d854e3edf8b9a3be324c3d136b6 release-1.9.8 ef107f3ddc237a3007e2769ec04adde0dcf627fa release-1.9.9 be00ca08e41a69e585b6aff70a725ed6c9e1a876 release-1.9.10 +fe66cff450a95beed36a2515210eb2d7ef62c9d3 release-1.9.11 From ahutchings at nginx.com Tue Feb 9 14:41:12 2016 From: ahutchings at nginx.com (Andrew Hutchings) Date: Tue, 9 Feb 2016 14:41:12 +0000 Subject: NGINX Dynamic Modules Message-ID: <56B9FA88.40003@nginx.com> Hi all, As you may have seen with recent code drops, we have released the initial version of our Dynamic Modules code to the source tree and NGINX 1.9.11. This initial release will allow you to compile modules with NGINX as before, but can create shared object files at the same time as the NGINX binary. These shared objects can then be loaded and unloaded at runtime. If you have any modules which you wish to use with this new feature they will need a little work to convert them. Specifically the way the ?config? file is written has changed. Although we have maintained compatibility with the static compilation of modules so if you do not wish to convert a module then you won?t have to change anything. Details on the new format and how to convert the modules can be found at: https://www.nginx.com/resources/wiki/extending/ In addition we are working on fully documenting the module API with examples. This will come at a later date. If you have any questions or problems converting modules please let us know on this mailing list. Kind Regards -- Andrew Hutchings (LinuxJedi) Technical Product Manager, NGINX Inc. From pavel2000 at ngs.ru Tue Feb 9 18:09:09 2016 From: pavel2000 at ngs.ru (Pavel V. Rochnyack) Date: Wed, 10 Feb 2016 00:09:09 +0600 Subject: [PATCH] Limit conn: Added "off" parameter to the 'limit_conn' directive Message-ID: # HG changeset patch # User Pavel V. Rochnyack # Date 1454835814 -21600 # Node ID b4748ebdd06ba79aa27e0c54fc1d627d13966bed # Parent 3577c021f21eb4de6d09c1d624ba77ee9ee1eb6d Limit conn: Added "off" parameter to the 'limit_conn' directive. Added support for inherited "limit_conn" directives disable. diff -r 3577c021f21e -r b4748ebdd06b src/http/modules/ngx_http_limit_conn_module.c --- a/src/http/modules/ngx_http_limit_conn_module.c Fri Feb 05 21:48:25 2016 +0300 +++ b/src/http/modules/ngx_http_limit_conn_module.c Sun Feb 07 15:03:34 2016 +0600 @@ -40,6 +40,7 @@ typedef struct { ngx_array_t limits; ngx_uint_t log_level; ngx_uint_t status_code; + ngx_uint_t off; /* unsigned off:1 */ } ngx_http_limit_conn_conf_t; @@ -82,7 +83,7 @@ static ngx_command_t ngx_http_limit_con NULL }, { ngx_string("limit_conn"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, ngx_http_limit_conn, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -160,6 +161,10 @@ ngx_http_limit_conn_handler(ngx_http_req lccf = ngx_http_get_module_loc_conf(r, ngx_http_limit_conn_module); limits = lccf->limits.elts; + if (lccf->off) { + return NGX_DECLINED; + } + for (i = 0; i < lccf->limits.nelts; i++) { ctx = limits[i].shm_zone->data; @@ -466,6 +471,7 @@ ngx_http_limit_conn_create_conf(ngx_conf conf->log_level = NGX_CONF_UNSET_UINT; conf->status_code = NGX_CONF_UNSET_UINT; + conf->off = NGX_CONF_UNSET_UINT; return conf; } @@ -477,7 +483,9 @@ ngx_http_limit_conn_merge_conf(ngx_conf_ ngx_http_limit_conn_conf_t *prev = parent; ngx_http_limit_conn_conf_t *conf = child; - if (conf->limits.elts == NULL) { + ngx_conf_merge_uint_value(conf->off, prev->off, 0); + + if (conf->off == 0 && conf->limits.elts == NULL) { conf->limits = prev->limits; } @@ -603,6 +611,35 @@ ngx_http_limit_conn(ngx_conf_t *cf, ngx_ value = cf->args->elts; + ngx_conf_merge_uint_value(lccf->off, lccf->off, 0); + + if (ngx_strcmp(value[1].data, "off") == 0) { + if (cf->args->nelts != 2) { + return "has invalid number of arguments"; + } + + if (lccf->off || lccf->limits.elts) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"limit_conn off\" cannot be used with other " + "\"limit_conn\" directives on the same level"); + return NGX_CONF_ERROR; + } + + lccf->off = 1; + return NGX_CONF_OK; + } + + if (cf->args->nelts != 3) { + return "has invalid number of arguments"; + } + + if (lccf->off) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"limit_conn off\" cannot be used with other " + "\"limit_conn\" directives on the same level"); + return NGX_CONF_ERROR; + } + shm_zone = ngx_shared_memory_add(cf, &value[1], 0, &ngx_http_limit_conn_module); if (shm_zone == NULL) { From pavel2000 at ngs.ru Tue Feb 9 18:09:33 2016 From: pavel2000 at ngs.ru (Pavel V. Rochnyack) Date: Wed, 10 Feb 2016 00:09:33 +0600 Subject: [PATCH] Limit req: Added "off" parameter to the 'limit_req' directive Message-ID: <42a41d68c88ff25514cb.1455041373@flash> # HG changeset patch # User Pavel V. Rochnyack # Date 1454835814 -21600 # Node ID 42a41d68c88ff25514cb501de657e8e8d54b5099 # Parent 3577c021f21eb4de6d09c1d624ba77ee9ee1eb6d Limit req: Added "off" parameter to the 'limit_req' directive. Added support for inherited "limit_req" directives disable. diff -r 3577c021f21e -r 42a41d68c88f src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c Fri Feb 05 21:48:25 2016 +0300 +++ b/src/http/modules/ngx_http_limit_req_module.c Sun Feb 07 15:03:34 2016 +0600 @@ -53,6 +53,7 @@ typedef struct { ngx_uint_t limit_log_level; ngx_uint_t delay_log_level; ngx_uint_t status_code; + ngx_uint_t off; /* unsigned off:1 */ } ngx_http_limit_req_conf_t; @@ -172,6 +173,10 @@ ngx_http_limit_req_handler(ngx_http_requ lrcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_req_module); limits = lrcf->limits.elts; + if (lrcf->off) { + return NGX_DECLINED; + } + excess = 0; rc = NGX_DECLINED; @@ -698,6 +703,7 @@ ngx_http_limit_req_create_conf(ngx_conf_ conf->limit_log_level = NGX_CONF_UNSET_UINT; conf->status_code = NGX_CONF_UNSET_UINT; + conf->off = NGX_CONF_UNSET_UINT; return conf; } @@ -709,7 +715,9 @@ ngx_http_limit_req_merge_conf(ngx_conf_t ngx_http_limit_req_conf_t *prev = parent; ngx_http_limit_req_conf_t *conf = child; - if (conf->limits.elts == NULL) { + ngx_conf_merge_uint_value(conf->off, prev->off, 0); + + if (conf->off == 0 && conf->limits.elts == NULL) { conf->limits = prev->limits; } @@ -870,6 +878,31 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c value = cf->args->elts; + ngx_conf_merge_uint_value(lrcf->off, lrcf->off, 0); + + if (ngx_strcmp(value[1].data, "off") == 0) { + if (cf->args->nelts != 2) { + return "has invalid number of arguments"; + } + + if (lrcf->off || lrcf->limits.elts) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"limit_req off\" cannot be used with other " + "\"limit_req\" directives on the same level"); + return NGX_CONF_ERROR; + } + + lrcf->off = 1; + return NGX_CONF_OK; + } + + if (lrcf->off) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"limit_req off\" cannot be used with other " + "\"limit_req\" directives on the same level"); + return NGX_CONF_ERROR; + } + shm_zone = NULL; burst = 0; nodelay = 0; From jefftk at google.com Tue Feb 9 18:45:46 2016 From: jefftk at google.com (Jeff Kaufman) Date: Tue, 9 Feb 2016 13:45:46 -0500 Subject: NGINX Dynamic Modules In-Reply-To: <56B9FA88.40003@nginx.com> References: <56B9FA88.40003@nginx.com> Message-ID: This is very exciting! Among other things, this should make it practical for distributions to package individual nginx modules separately. We've been looking at whether this would let us offer a precompiled ngx_pagespeed module, though, and it looks to me like this might be pretty tricky? In order to load a module, it looks like it has to have been compiled for that specific point release of nginx and with a matching signature? So we would need to make binaries for 1.9.11, 1.9.12, 1.9.13 etc and for each of those we would need to make ones for each of the common signatures [1]. That's a lot of binaries to prepare! Have you been thinking about any way that a module could be built to run against many versions of nginx, and many signatures, if it doesn't touch pieces of nginx that differ? With Apache, for example, we prepare 32 bit and 64 bit binaries for the 2.2 series and the 2.4 series (so 4 binaries). This works because we're calling into an ABI that Apache is committed to keep the same, but there might be some other way that would work better for nginx. Jeff Kaufman PageSpeed TL [1] With there being 33 bits in the signature, we're not going to be preparing 2^33 modules for each nginx release, but there are probably common patterns of build-time feature availability. On Tue, Feb 9, 2016 at 9:41 AM, Andrew Hutchings wrote: > Hi all, > > As you may have seen with recent code drops, we have released the initial > version of our Dynamic Modules code to the source tree and NGINX 1.9.11. > This initial release will allow you to compile modules with NGINX as before, > but can create shared object files at the same time as the NGINX binary. > These shared objects can then be loaded and unloaded at runtime. > > If you have any modules which you wish to use with this new feature they > will need a little work to convert them. Specifically the way the ?config? > file is written has changed. Although we have maintained compatibility with > the static compilation of modules so if you do not wish to convert a module > then you won?t have to change anything. Details on the new format and how to > convert the modules can be found at: > > https://www.nginx.com/resources/wiki/extending/ > > In addition we are working on fully documenting the module API with > examples. This will come at a later date. > > If you have any questions or problems converting modules please let us know > on this mailing list. > > Kind Regards > -- > Andrew Hutchings (LinuxJedi) > Technical Product Manager, NGINX Inc. > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From ahutchings at nginx.com Tue Feb 9 20:29:07 2016 From: ahutchings at nginx.com (Andrew Hutchings) Date: Tue, 9 Feb 2016 20:29:07 +0000 Subject: NGINX Dynamic Modules In-Reply-To: References: <56B9FA88.40003@nginx.com> Message-ID: <56BA4C13.8020105@nginx.com> Hi Jeff, That is an interesting point about the signatures and something I can discuss internally. I have an alternative idea specifically for ngx_pagespeed. I'll contact you off-list about it in the next 24 hours. Kind Regards Andrew On 09/02/16 18:45, Jeff Kaufman wrote: > This is very exciting! Among other things, this should make it > practical for distributions to package individual nginx modules > separately. > > We've been looking at whether this would let us offer a precompiled > ngx_pagespeed module, though, and it looks to me like this might be > pretty tricky? In order to load a module, it looks like it has to > have been compiled for that specific point release of nginx and with a > matching signature? So we would need to make binaries for 1.9.11, > 1.9.12, 1.9.13 etc and for each of those we would need to make ones > for each of the common signatures [1]. That's a lot of binaries to > prepare! > > Have you been thinking about any way that a module could be built to > run against many versions of nginx, and many signatures, if it doesn't > touch pieces of nginx that differ? With Apache, for example, we > prepare 32 bit and 64 bit binaries for the 2.2 series and the 2.4 > series (so 4 binaries). This works because we're calling into an ABI > that Apache is committed to keep the same, but there might be some > other way that would work better for nginx. > > Jeff Kaufman > PageSpeed TL > > [1] With there being 33 bits in the signature, we're not going to be > preparing 2^33 modules for each nginx release, but there are probably > common patterns of build-time feature availability. > > On Tue, Feb 9, 2016 at 9:41 AM, Andrew Hutchings wrote: >> Hi all, >> >> As you may have seen with recent code drops, we have released the initial >> version of our Dynamic Modules code to the source tree and NGINX 1.9.11. >> This initial release will allow you to compile modules with NGINX as before, >> but can create shared object files at the same time as the NGINX binary. >> These shared objects can then be loaded and unloaded at runtime. >> >> If you have any modules which you wish to use with this new feature they >> will need a little work to convert them. Specifically the way the ?config? >> file is written has changed. Although we have maintained compatibility with >> the static compilation of modules so if you do not wish to convert a module >> then you won?t have to change anything. Details on the new format and how to >> convert the modules can be found at: >> >> https://www.nginx.com/resources/wiki/extending/ >> >> In addition we are working on fully documenting the module API with >> examples. This will come at a later date. >> >> If you have any questions or problems converting modules please let us know >> on this mailing list. >> >> Kind Regards >> -- >> Andrew Hutchings (LinuxJedi) >> Technical Product Manager, NGINX Inc. >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Andrew Hutchings (LinuxJedi) Technical Product Manager, NGINX Inc. From mdounin at mdounin.ru Tue Feb 9 23:39:46 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 10 Feb 2016 02:39:46 +0300 Subject: NGINX Dynamic Modules In-Reply-To: References: <56B9FA88.40003@nginx.com> Message-ID: <20160209233946.GM70672@mdounin.ru> Hello! On Tue, Feb 09, 2016 at 01:45:46PM -0500, Jeff Kaufman wrote: > This is very exciting! Among other things, this should make it > practical for distributions to package individual nginx modules > separately. That's the main task which is expected to be solved at this point, yes. > We've been looking at whether this would let us offer a precompiled > ngx_pagespeed module, though, and it looks to me like this might be > pretty tricky? In order to load a module, it looks like it has to > have been compiled for that specific point release of nginx and with a > matching signature? So we would need to make binaries for 1.9.11, > 1.9.12, 1.9.13 etc and for each of those we would need to make ones > for each of the common signatures [1]. That's a lot of binaries to > prepare! Yes. We don't maintain a stable ABI between versions, and not even API between mainline versions. So preparing different binaries for different nginx versions is unavoidable for now. As of now general idea is that it should be possible to compile module that can be loaded into an nginx binary built on a particular OS with particular configure arguments. That is, you can prepare binaries targeting particular nginx distributions. In the future we are likely to review and reduce number of various options that change nginx internal structures and hence are included in the signature. This should improve compatibility between different builds. > Have you been thinking about any way that a module could be built to > run against many versions of nginx, and many signatures, if it doesn't > touch pieces of nginx that differ? With Apache, for example, we > prepare 32 bit and 64 bit binaries for the 2.2 series and the 2.4 > series (so 4 binaries). This works because we're calling into an ABI > that Apache is committed to keep the same, but there might be some > other way that would work better for nginx. The idea of signatures and version checks is to make sure that a module and nginx ideas about API structures agree. So running against "many signatures" looks like a wrong idea, but see above about reducing granularity of signatures. We can also consider providing stable ABI in addition to API in stable branches, but this probably don't make a lot of sense as stable releases aren't happening often. -- Maxim Dounin http://nginx.org/ From piotrsikora at google.com Wed Feb 10 00:32:11 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 09 Feb 2016 16:32:11 -0800 Subject: [PATCH] Core: fix ngx_module_t Message-ID: <4589af8229973093d328.1455064331@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1455064286 28800 # Tue Feb 09 16:31:26 2016 -0800 # Node ID 4589af8229973093d3287fc3747e1a5245eaaf59 # Parent 50770821c184a79f3da1707c15e6c835a3596b97 Core: fix ngx_module_t. Changes to NGX_MODULE_V1 and ngx_module_t in 85dea406e18f (1.9.11) broke all modules written in C++, because ISO C++11 does not allow conversion from string literal to char *. Signed-off-by: Piotr Sikora diff -r 50770821c184 -r 4589af822997 src/core/ngx_module.h --- a/src/core/ngx_module.h +++ b/src/core/ngx_module.h @@ -253,7 +253,7 @@ struct ngx_module_s { ngx_uint_t spare1; ngx_uint_t version; - char *signature; + const char *signature; void *ctx; ngx_command_t *commands; From mdounin at mdounin.ru Wed Feb 10 03:26:37 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 10 Feb 2016 03:26:37 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/3baf9aa36a79 branches: changeset: 6389:3baf9aa36a79 user: Maxim Dounin date: Wed Feb 10 06:23:34 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 1009011 -#define NGINX_VERSION "1.9.11" +#define nginx_version 1009012 +#define NGINX_VERSION "1.9.12" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From mdounin at mdounin.ru Wed Feb 10 03:26:40 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 10 Feb 2016 03:26:40 +0000 Subject: [nginx] Core: ngx_module_t compatibility with C++. Message-ID: details: http://hg.nginx.org/nginx/rev/ff1e625ae55b branches: changeset: 6390:ff1e625ae55b user: Piotr Sikora date: Tue Feb 09 16:31:26 2016 -0800 description: Core: ngx_module_t compatibility with C++. Changes to NGX_MODULE_V1 and ngx_module_t in 85dea406e18f (1.9.11) broke all modules written in C++, because ISO C++11 does not allow conversion from string literal to char *. Signed-off-by: Piotr Sikora diffstat: src/core/ngx_module.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): 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 @@ -253,7 +253,7 @@ struct ngx_module_s { ngx_uint_t spare1; ngx_uint_t version; - char *signature; + const char *signature; void *ctx; ngx_command_t *commands; From mdounin at mdounin.ru Wed Feb 10 03:27:31 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 10 Feb 2016 06:27:31 +0300 Subject: [PATCH] Core: fix ngx_module_t In-Reply-To: <4589af8229973093d328.1455064331@piotrsikora.sfo.corp.google.com> References: <4589af8229973093d328.1455064331@piotrsikora.sfo.corp.google.com> Message-ID: <20160210032731.GN70672@mdounin.ru> Hello! On Tue, Feb 09, 2016 at 04:32:11PM -0800, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1455064286 28800 > # Tue Feb 09 16:31:26 2016 -0800 > # Node ID 4589af8229973093d3287fc3747e1a5245eaaf59 > # Parent 50770821c184a79f3da1707c15e6c835a3596b97 > Core: fix ngx_module_t. > > Changes to NGX_MODULE_V1 and ngx_module_t in 85dea406e18f (1.9.11) > broke all modules written in C++, because ISO C++11 does not allow > conversion from string literal to char *. > > Signed-off-by: Piotr Sikora > > diff -r 50770821c184 -r 4589af822997 src/core/ngx_module.h > --- a/src/core/ngx_module.h > +++ b/src/core/ngx_module.h > @@ -253,7 +253,7 @@ struct ngx_module_s { > ngx_uint_t spare1; > > ngx_uint_t version; > - char *signature; > + const char *signature; > > void *ctx; > ngx_command_t *commands; Committed with minor changes to commit log, thanks. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Feb 10 04:17:20 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 10 Feb 2016 07:17:20 +0300 Subject: [PATCH] Limit conn: Added "off" parameter to the 'limit_conn' directive In-Reply-To: References: Message-ID: <20160210041720.GO70672@mdounin.ru> Hello! On Wed, Feb 10, 2016 at 12:09:09AM +0600, Pavel V. Rochnyack wrote: > # HG changeset patch > # User Pavel V. Rochnyack > # Date 1454835814 -21600 > # Node ID b4748ebdd06ba79aa27e0c54fc1d627d13966bed > # Parent 3577c021f21eb4de6d09c1d624ba77ee9ee1eb6d > Limit conn: Added "off" parameter to the 'limit_conn' directive. Please do not capitalize "Added". Please do not use different quotes. Something like Limit conn: added "limit_conn off". should be good enough. > > Added support for inherited "limit_conn" directives disable. This probably can be safely omitted. Alternatively, please rewrite to something more readable, e.g.: The "limit_conn" directive with the "off" parameter allows to disable inheritance of limits from the previous level. > > diff -r 3577c021f21e -r b4748ebdd06b src/http/modules/ngx_http_limit_conn_module.c > --- a/src/http/modules/ngx_http_limit_conn_module.c Fri Feb 05 21:48:25 2016 +0300 > +++ b/src/http/modules/ngx_http_limit_conn_module.c Sun Feb 07 15:03:34 2016 +0600 > @@ -40,6 +40,7 @@ typedef struct { > ngx_array_t limits; > ngx_uint_t log_level; > ngx_uint_t status_code; > + ngx_uint_t off; /* unsigned off:1 */ > } ngx_http_limit_conn_conf_t; > > > @@ -82,7 +83,7 @@ static ngx_command_t ngx_http_limit_con > NULL }, > > { ngx_string("limit_conn"), > - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, > + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, > ngx_http_limit_conn, > NGX_HTTP_LOC_CONF_OFFSET, > 0, > @@ -160,6 +161,10 @@ ngx_http_limit_conn_handler(ngx_http_req > lccf = ngx_http_get_module_loc_conf(r, ngx_http_limit_conn_module); > limits = lccf->limits.elts; > > + if (lccf->off) { > + return NGX_DECLINED; > + } > + This check should not be needed once configuration parsing properly implemented, as lccf->limits.nelts below will be 0 and the for() loop will do nothing. > for (i = 0; i < lccf->limits.nelts; i++) { > ctx = limits[i].shm_zone->data; > > @@ -466,6 +471,7 @@ ngx_http_limit_conn_create_conf(ngx_conf > > conf->log_level = NGX_CONF_UNSET_UINT; > conf->status_code = NGX_CONF_UNSET_UINT; > + conf->off = NGX_CONF_UNSET_UINT; > > return conf; > } > @@ -477,7 +483,9 @@ ngx_http_limit_conn_merge_conf(ngx_conf_ > ngx_http_limit_conn_conf_t *prev = parent; > ngx_http_limit_conn_conf_t *conf = child; > > - if (conf->limits.elts == NULL) { > + ngx_conf_merge_uint_value(conf->off, prev->off, 0); > + > + if (conf->off == 0 && conf->limits.elts == NULL) { > conf->limits = prev->limits; > } > > @@ -603,6 +611,35 @@ ngx_http_limit_conn(ngx_conf_t *cf, ngx_ > > value = cf->args->elts; > > + ngx_conf_merge_uint_value(lccf->off, lccf->off, 0); Merging the value with itself looks like a dirty hack. Correct solution would be to set conf->off to 0 in create_conf, and don't try to merge it neither here nor in merge_conf. > + > + if (ngx_strcmp(value[1].data, "off") == 0) { > + if (cf->args->nelts != 2) { > + return "has invalid number of arguments"; > + } > + > + if (lccf->off || lccf->limits.elts) { > + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > + "\"limit_conn off\" cannot be used with other " > + "\"limit_conn\" directives on the same level"); > + return NGX_CONF_ERROR; > + } > + > + lccf->off = 1; > + return NGX_CONF_OK; > + } > + > + if (cf->args->nelts != 3) { > + return "has invalid number of arguments"; > + } > + > + if (lccf->off) { > + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > + "\"limit_conn off\" cannot be used with other " > + "\"limit_conn\" directives on the same level"); > + return NGX_CONF_ERROR; > + } > + This looks overcomplicated and far from what nginx normally prints on similar errors at the same time. It should be possible to do this better. > shm_zone = ngx_shared_memory_add(cf, &value[1], 0, > &ngx_http_limit_conn_module); > if (shm_zone == NULL) { -- Maxim Dounin http://nginx.org/ p.s. Not --reply-to, but --in-reply-to. From pavel2000 at ngs.ru Wed Feb 10 05:31:42 2016 From: pavel2000 at ngs.ru (Pavel V.) Date: Wed, 10 Feb 2016 11:31:42 +0600 Subject: [PATCH] Limit conn: Added "off" parameter to the 'limit_conn' directive In-Reply-To: <20160210041720.GO70672@mdounin.ru> References: <20160210041720.GO70672@mdounin.ru> Message-ID: <152676708.20160210113142@ngs.ru> Hi, Maxim! Thanks for reviewing my patches. >> + >> + if (ngx_strcmp(value[1].data, "off") == 0) { >> + if (cf->args->nelts != 2) { >> + return "has invalid number of arguments"; >> + } >> + >> + if (lccf->off || lccf->limits.elts) { >> + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, >> + "\"limit_conn off\" cannot be used with other " >> + "\"limit_conn\" directives on the same level"); >> + return NGX_CONF_ERROR; >> + } >> + >> + lccf->off = 1; >> + return NGX_CONF_OK; >> + } >> + >> + if (cf->args->nelts != 3) { >> + return "has invalid number of arguments"; >> + } >> + >> + if (lccf->off) { >> + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, >> + "\"limit_conn off\" cannot be used with other " >> + "\"limit_conn\" directives on the same level"); >> + return NGX_CONF_ERROR; >> + } >> + > This looks overcomplicated and far from what nginx normally prints > on similar errors at the same time. It should be possible to do > this better. Will the "'limit_conn' directive already defined with conflicting parameters" message be suitable in this case? Which one should I use - ngx_conf_log_error() or return 'already defined with conflicting parameter'? -- Regards, Pavel mailto:pavel2000 at ngs.ru From vbart at nginx.com Wed Feb 10 13:37:29 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 10 Feb 2016 16:37:29 +0300 Subject: [PATCH] Limit conn: Added "off" parameter to the 'limit_conn' directive In-Reply-To: References: Message-ID: <2165185.vmRscvAtK3@vbart-workstation> On Wednesday 10 February 2016 00:09:09 Pavel V. Rochnyack wrote: > # HG changeset patch > # User Pavel V. Rochnyack > # Date 1454835814 -21600 > # Node ID b4748ebdd06ba79aa27e0c54fc1d627d13966bed > # Parent 3577c021f21eb4de6d09c1d624ba77ee9ee1eb6d > Limit conn: Added "off" parameter to the 'limit_conn' directive. > > Added support for inherited "limit_conn" directives disable. > > diff -r 3577c021f21e -r b4748ebdd06b src/http/modules/ngx_http_limit_conn_module.c > --- a/src/http/modules/ngx_http_limit_conn_module.c Fri Feb 05 21:48:25 2016 +0300 > +++ b/src/http/modules/ngx_http_limit_conn_module.c Sun Feb 07 15:03:34 2016 +0600 > @@ -40,6 +40,7 @@ typedef struct { > ngx_array_t limits; > ngx_uint_t log_level; > ngx_uint_t status_code; > + ngx_uint_t off; /* unsigned off:1 */ > } ngx_http_limit_conn_conf_t; [..] Instead of adding additional flag, it should be possible to replace the "limits" array with a pointer and use NULL as an indicator of the "off" value. That should simplify the code. wbr, Valentin V. Bartenev From ru at nginx.com Wed Feb 10 13:44:51 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 10 Feb 2016 13:44:51 +0000 Subject: [nginx] Dynamic modules: added auth_basic module libs via ngx_mo... Message-ID: details: http://hg.nginx.org/nginx/rev/965e4223e702 branches: changeset: 6391:965e4223e702 user: Ruslan Ermilov date: Wed Feb 10 11:36:25 2016 +0300 description: Dynamic modules: added auth_basic module libs via ngx_module_libs=. diffstat: auto/modules | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (16 lines): diff -r ff1e625ae55b -r 965e4223e702 auto/modules --- a/auto/modules Tue Feb 09 16:31:26 2016 -0800 +++ b/auto/modules Wed Feb 10 11:36:25 2016 +0300 @@ -530,11 +530,10 @@ if [ $HTTP_AUTH_BASIC = YES ]; then ngx_module_incs= ngx_module_deps= ngx_module_srcs=src/http/modules/ngx_http_auth_basic_module.c - ngx_module_libs= + ngx_module_libs=$CRYPT_LIB ngx_module_link=$HTTP_AUTH_BASIC . auto/module - CORE_LIBS="$CORE_LIBS $CRYPT_LIB" fi if [ $HTTP_ACCESS = YES ]; then From mdounin at mdounin.ru Wed Feb 10 13:53:16 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 10 Feb 2016 16:53:16 +0300 Subject: [PATCH] Limit conn: Added "off" parameter to the 'limit_conn' directive In-Reply-To: <152676708.20160210113142@ngs.ru> References: <20160210041720.GO70672@mdounin.ru> <152676708.20160210113142@ngs.ru> Message-ID: <20160210135316.GT70672@mdounin.ru> Hello! On Wed, Feb 10, 2016 at 11:31:42AM +0600, Pavel V. wrote: > Hi, Maxim! > > Thanks for reviewing my patches. > > >> + > >> + if (ngx_strcmp(value[1].data, "off") == 0) { > >> + if (cf->args->nelts != 2) { > >> + return "has invalid number of arguments"; > >> + } > >> + > >> + if (lccf->off || lccf->limits.elts) { > >> + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > >> + "\"limit_conn off\" cannot be used with other " > >> + "\"limit_conn\" directives on the same level"); > >> + return NGX_CONF_ERROR; > >> + } > >> + > >> + lccf->off = 1; > >> + return NGX_CONF_OK; > >> + } > >> + > >> + if (cf->args->nelts != 3) { > >> + return "has invalid number of arguments"; > >> + } > >> + > >> + if (lccf->off) { > >> + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > >> + "\"limit_conn off\" cannot be used with other " > >> + "\"limit_conn\" directives on the same level"); > >> + return NGX_CONF_ERROR; > >> + } > >> + > > > This looks overcomplicated and far from what nginx normally prints > > on similar errors at the same time. It should be possible to do > > this better. > > Will the "'limit_conn' directive already defined with conflicting parameters" > message be suitable in this case? > Which one should I use - ngx_conf_log_error() or > return 'already defined with conflicting parameter'? I would use something like return "conflicts with previous limits"; or something like this. Though I haven't really tried and there may be better options. -- Maxim Dounin http://nginx.org/ From sam at surround.io Wed Feb 10 22:38:43 2016 From: sam at surround.io (Sam McKelvie) Date: Wed, 10 Feb 2016 14:38:43 -0800 Subject: Proposed changeset to fix client cert from ngx_ssl_get_certificate passed as HTTP header value In-Reply-To: <20160205155811.GP70403@mdounin.ru> References: <20160204182928.GF70403@mdounin.ru> <20160205155811.GP70403@mdounin.ru> Message-ID: OK, sorry for the delay. Here is a changeset that implements $ssl_client_escaped_certificate, following your latest comments. It works well with node/express. OK with this? ~Sam # HG changeset patch # User Sam McKelvie # Date 1455143619 28800 # Wed Feb 10 14:33:39 2016 -0800 # Node ID f3f2dbd8340f04adccd805ff5a8547e10e6fa874 # Parent e0d7c2f718515d4c48e5ed2a0643294da60cf2ba Define a new $ssl_client_escaped_certificate variable that is the URL-encoded form of the raw PEM client certificate. This variable is always appropriate for inclusion in proxy_set_header values, unlike the $ssl_client_cert variable, which includes '\n' characters that are not prefixed by '\r', breaking some http servers (e.g., node/express). Per Maxim, $ssl_client_cert should eventually be deprecated. Users of $ssl_client_cert should move to ssl_client_scaped_certificate. Tested with node/express and nginx-tests. diff -r e0d7c2f71851 -r f3f2dbd8340f src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Fri Feb 05 14:02:54 2016 +0300 +++ b/src/event/ngx_event_openssl.c Wed Feb 10 14:33:39 2016 -0800 @@ -3273,6 +3273,42 @@ ngx_int_t +ngx_ssl_get_escaped_certificate(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s) +{ + size_t len; + ngx_str_t cert; + uintptr_t escape; + + s->data = NULL; + s->len = 0; + + if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) { + return NGX_ERROR; + } + + escape = ngx_escape_uri(NULL, cert.data, cert.len, + NGX_ESCAPE_URI_COMPONENT); + + /* Each escaped character adds 2 characters to result */ + len = cert.len + 2 * escape; + + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + ngx_pfree(pool, cert.data); + return NGX_ERROR; + } + s->len = len; + + ngx_escape_uri(s->data, cert.data, cert.len, NGX_ESCAPE_URI_COMPONENT); + + ngx_pfree(pool, cert.data); + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { char *p; diff -r e0d7c2f71851 -r f3f2dbd8340f src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h Fri Feb 05 14:02:54 2016 +0300 +++ b/src/event/ngx_event_openssl.h Wed Feb 10 14:33:39 2016 -0800 @@ -180,6 +180,8 @@ ngx_str_t *s); ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_escaped_certificate(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, diff -r e0d7c2f71851 -r f3f2dbd8340f src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c Fri Feb 05 14:02:54 2016 +0300 +++ b/src/http/modules/ngx_http_ssl_module.c Wed Feb 10 14:33:39 2016 -0800 @@ -292,6 +292,9 @@ (uintptr_t) ngx_ssl_get_raw_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_escaped_cert"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_escaped_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 }, On Fri, Feb 5, 2016 at 7:58 AM, Maxim Dounin wrote: > Hello! > > On Thu, Feb 04, 2016 at 01:38:48PM -0800, Sam McKelvie wrote: > >> I think it is your call if you want to make a breaking change to >> $ssl_client_cert to URL encode it; I'd be happy to submit the >> changeset if you would approve that, but I personally don't feel >> comfortable breaking any existing applications that parse/decode the >> certificate. > > No, certainly not something I want to be done. > >> So my suggestion now is to define a new $ssl_client_cert_url_encoded >> variable that is the URL-encoded form of the raw PEM certificate. With >> your approval I will submit a changeset for that... > > Yes, adding a variable with an URL-escaped versions looks like a > way to go. I disagree with the name you suggest though, I think > that something like $ssl_client_escaped_cert would be more in line > with $ssl_client_cert and $ssl_client_raw_cert variables we > currently have and the ngx_escape_uri() function nginx uses > internally. > > Some more background. As of now we have: > > - $ssl_client_raw_cert - client cert in PEM format > - $ssl_client_cert - client cert in PEM format with \t added > > At some distant point in the future we probably want to have: > > - $ssl_client_cert - client cert in PEM format > - a way to urlescape() things, see > https://trac.nginx.org/nginx/ticket/52 > > At this point, an escaped version of the client cert will be > available as something like ${urlescape($ssl_client_cert)}. All > uses of client cert with tabs are expected to disappear. There > are a couple of problems though: > > - there are existing uses of $ssl_client_cert and > $ssl_client_raw_cert, breaking them would be bad; > > - we don't have urlescape() function in configs, and probably > won't have it in a near future. > > So we have to figure out some migration plan, e.g.: > > - introduce $ssl_client_escaped_cert, with urlescaped PEM cert; > > - introduce $ssl_client_tabbed_cert as an alias to > $ssl_client_cert (with PEM cert with tabs); > > - change $ssl_client_cert back to be raw cert (preserving > $ssl_client_raw_cert as a deprecated alias for some time); > > - do something with $ssl_client_tabbed_cert at some point, not > sure; > > - once urlescape() functionality is added, deprecate > $ssl_client_escaped_cert, suggesting to use > urlescape($ssl_client_cert) instead. > > Not sure if it's an optimal plan and if we are actually going to > follow it, but introducing $ssl_client_escaped_cert looks like a > more or less obvious 1st step, at least if we don't expect > urlescape() to appear in the near future. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From arut at nginx.com Thu Feb 11 11:33:57 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Thu, 11 Feb 2016 11:33:57 +0000 Subject: [nginx] Stream: removed useless typedef. Message-ID: details: http://hg.nginx.org/nginx/rev/4eb1b5c6d9c6 branches: changeset: 6392:4eb1b5c6d9c6 user: Roman Arutyunyan date: Thu Feb 11 14:20:22 2016 +0300 description: Stream: removed useless typedef. diffstat: src/stream/ngx_stream_proxy_module.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diffs (13 lines): diff -r 965e4223e702 -r 4eb1b5c6d9c6 src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Wed Feb 10 11:36:25 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Thu Feb 11 14:20:22 2016 +0300 @@ -10,9 +10,6 @@ #include -typedef void (*ngx_stream_proxy_handler_pt)(ngx_stream_session_t *s); - - typedef struct { ngx_msec_t connect_timeout; ngx_msec_t timeout; From arut at nginx.com Thu Feb 11 11:33:59 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Thu, 11 Feb 2016 11:33:59 +0000 Subject: [nginx] Stream: initialize variable right before using it. Message-ID: details: http://hg.nginx.org/nginx/rev/70e6e1f12dee branches: changeset: 6393:70e6e1f12dee user: Roman Arutyunyan date: Thu Feb 11 14:20:26 2016 +0300 description: Stream: initialize variable right before using it. diffstat: src/stream/ngx_stream_proxy_module.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 4eb1b5c6d9c6 -r 70e6e1f12dee src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Thu Feb 11 14:20:22 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Thu Feb 11 14:20:26 2016 +0300 @@ -432,8 +432,6 @@ ngx_stream_proxy_connect(ngx_stream_sess ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc); - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - if (rc == NGX_ERROR) { ngx_stream_proxy_finalize(s, NGX_ERROR); return; @@ -468,6 +466,8 @@ ngx_stream_proxy_connect(ngx_stream_sess pc->read->handler = ngx_stream_proxy_connect_handler; pc->write->handler = ngx_stream_proxy_connect_handler; + pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); + ngx_add_timer(pc->write, pscf->connect_timeout); } From ru at nginx.com Thu Feb 11 15:52:52 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 11 Feb 2016 15:52:52 +0000 Subject: [nginx] Dynamic modules: fixed a version mismatch message (ticke... Message-ID: details: http://hg.nginx.org/nginx/rev/5fe617f38222 branches: changeset: 6394:5fe617f38222 user: Ruslan Ermilov date: Thu Feb 11 18:46:46 2016 +0300 description: Dynamic modules: fixed a version mismatch message (ticket #898). Based on a patch by Takashi Takizawa. diffstat: src/core/ngx_module.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 70e6e1f12dee -r 5fe617f38222 src/core/ngx_module.c --- a/src/core/ngx_module.c Thu Feb 11 14:20:26 2016 +0300 +++ b/src/core/ngx_module.c Thu Feb 11 18:46:46 2016 +0300 @@ -171,7 +171,7 @@ ngx_add_module(ngx_conf_t *cf, ngx_str_t if (module->version != nginx_version) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "module \"%V\" version %ui instead of %ui", - file, module->version, nginx_version); + file, module->version, (ngx_uint_t) nginx_version); return NGX_ERROR; } From vbart at nginx.com Thu Feb 11 16:30:23 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 11 Feb 2016 16:30:23 +0000 Subject: [nginx] HTTP/2: implemented HPACK Huffman encoding for response ... Message-ID: details: http://hg.nginx.org/nginx/rev/ba3c2ca21aa5 branches: changeset: 6395:ba3c2ca21aa5 user: Valentin Bartenev date: Thu Feb 11 15:35:36 2016 +0300 description: HTTP/2: implemented HPACK Huffman encoding for response headers. This reduces the size of headers by over 30% on average. Based on the patch by Vlad Krasnov: http://mailman.nginx.org/pipermail/nginx-devel/2015-December/007682.html diffstat: auto/cc/conf | 10 + src/http/v2/ngx_http_v2.h | 2 + src/http/v2/ngx_http_v2_filter_module.c | 157 +++++++++++++------- src/http/v2/ngx_http_v2_huff_encode.c | 240 ++++++++++++++++++++++++++++++++ 4 files changed, 353 insertions(+), 56 deletions(-) diffs (558 lines): diff -r 5fe617f38222 -r ba3c2ca21aa5 auto/cc/conf --- a/auto/cc/conf Thu Feb 11 18:46:46 2016 +0300 +++ b/auto/cc/conf Thu Feb 11 15:35:36 2016 +0300 @@ -225,6 +225,16 @@ if [ "$NGX_PLATFORM" != win32 ]; then . auto/feature + ngx_feature="gcc builtin 64 bit byteswap" + ngx_feature_name="NGX_HAVE_GCC_BSWAP64" + ngx_feature_run=no + ngx_feature_incs= + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="__builtin_bswap64(0)" + . auto/feature + + # ngx_feature="inline" # ngx_feature_name= # ngx_feature_run=no diff -r 5fe617f38222 -r ba3c2ca21aa5 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Thu Feb 11 18:46:46 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Thu Feb 11 15:35:36 2016 +0300 @@ -274,6 +274,8 @@ ngx_int_t ngx_http_v2_table_size(ngx_htt ngx_int_t ngx_http_v2_huff_decode(u_char *state, u_char *src, size_t len, u_char **dst, ngx_uint_t last, ngx_log_t *log); +size_t ngx_http_v2_huff_encode(u_char *src, size_t len, u_char *dst, + ngx_uint_t lower); #define ngx_http_v2_prefix(bits) ((1 << (bits)) - 1) diff -r 5fe617f38222 -r ba3c2ca21aa5 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Thu Feb 11 18:46:46 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Thu Feb 11 15:35:36 2016 +0300 @@ -25,6 +25,11 @@ #define ngx_http_v2_indexed(i) (128 + (i)) #define ngx_http_v2_inc_indexed(i) (64 + (i)) +#define ngx_http_v2_write_name(dst, src, len, tmp) \ + ngx_http_v2_string_encode(dst, src, len, tmp, 1) +#define ngx_http_v2_write_value(dst, src, len, tmp) \ + ngx_http_v2_string_encode(dst, src, len, tmp, 0) + #define NGX_HTTP_V2_ENCODE_RAW 0 #define NGX_HTTP_V2_ENCODE_HUFF 0x80 @@ -46,6 +51,8 @@ #define NGX_HTTP_V2_VARY_INDEX 59 +static u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, + u_char *tmp, ngx_uint_t lower); static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, ngx_uint_t value); static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame( @@ -119,8 +126,8 @@ static ngx_http_output_header_filter_pt static ngx_int_t ngx_http_v2_header_filter(ngx_http_request_t *r) { - u_char status, *pos, *start, *p; - size_t len; + u_char status, *pos, *start, *p, *tmp; + size_t len, tmp_len; ngx_str_t host, location; ngx_uint_t i, port; ngx_list_part_t *part; @@ -136,6 +143,14 @@ ngx_http_v2_header_filter(ngx_http_reque #endif u_char addr[NGX_SOCKADDR_STRLEN]; + static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7"; +#if (NGX_HTTP_GZIP) + static const u_char accept_encoding[12] = + "\x8b\x84\x84\x2d\x69\x5b\x05\x44\x3c\x86\xaa\x6f"; +#endif + + static size_t nginx_ver_len = ngx_http_v2_literal_size(NGINX_VER); + static u_char nginx_ver[ngx_http_v2_literal_size(NGINX_VER)]; if (!r->stream) { return ngx_http_next_header_filter(r); @@ -215,8 +230,7 @@ ngx_http_v2_header_filter(ngx_http_reque clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->headers_out.server == NULL) { - len += 1 + (clcf->server_tokens ? ngx_http_v2_literal_size(NGINX_VER) - : ngx_http_v2_literal_size("nginx")); + len += 1 + (clcf->server_tokens ? nginx_ver_len : sizeof(nginx)); } if (r->headers_out.date == NULL) { @@ -340,10 +354,12 @@ ngx_http_v2_header_filter(ngx_http_reque len += 1 + NGX_HTTP_V2_INT_OCTETS + r->headers_out.location->value.len; } + tmp_len = len; + #if (NGX_HTTP_GZIP) if (r->gzip_vary) { if (clcf->gzip_vary) { - len += 1 + ngx_http_v2_literal_size("Accept-Encoding"); + len += 1 + sizeof(accept_encoding); } else { r->gzip_vary = 0; @@ -386,10 +402,20 @@ ngx_http_v2_header_filter(ngx_http_reque len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len + NGX_HTTP_V2_INT_OCTETS + header[i].value.len; + + if (header[i].key.len > tmp_len) { + tmp_len = header[i].key.len; + } + + if (header[i].value.len > tmp_len) { + tmp_len = header[i].value.len; + } } - pos = ngx_palloc(r->pool, len); - if (pos == NULL) { + tmp = ngx_palloc(r->pool, tmp_len); + pos = ngx_pnalloc(r->pool, len); + + if (pos == NULL || tmp == NULL) { return NGX_ERROR; } @@ -408,21 +434,23 @@ ngx_http_v2_header_filter(ngx_http_reque *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX); if (clcf->server_tokens) { - *pos++ = NGX_HTTP_V2_ENCODE_RAW | (sizeof(NGINX_VER) - 1); - pos = ngx_cpymem(pos, NGINX_VER, sizeof(NGINX_VER) - 1); + if (nginx_ver[0] == '\0') { + p = ngx_http_v2_write_value(nginx_ver, (u_char *) NGINX_VER, + sizeof(NGINX_VER) - 1, tmp); + nginx_ver_len = p - nginx_ver; + } + + pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len); } else { - *pos++ = NGX_HTTP_V2_ENCODE_RAW | (sizeof("nginx") - 1); - pos = ngx_cpymem(pos, "nginx", sizeof("nginx") - 1); + pos = ngx_cpymem(pos, nginx, sizeof(nginx)); } } if (r->headers_out.date == NULL) { *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_DATE_INDEX); - *pos++ = (u_char) ngx_cached_http_time.len; - - pos = ngx_cpymem(pos, ngx_cached_http_time.data, - ngx_cached_http_time.len); + pos = ngx_http_v2_write_value(pos, ngx_cached_http_time.data, + ngx_cached_http_time.len, tmp); } if (r->headers_out.content_type.len) { @@ -431,34 +459,30 @@ ngx_http_v2_header_filter(ngx_http_reque if (r->headers_out.content_type_len == r->headers_out.content_type.len && r->headers_out.charset.len) { - *pos = NGX_HTTP_V2_ENCODE_RAW; - pos = ngx_http_v2_write_int(pos, ngx_http_v2_prefix(7), - r->headers_out.content_type.len - + sizeof("; charset=") - 1 - + r->headers_out.charset.len); + len = r->headers_out.content_type.len + sizeof("; charset=") - 1 + + r->headers_out.charset.len; - p = pos; + p = ngx_pnalloc(r->pool, len); + if (p == NULL) { + return NGX_ERROR; + } - pos = ngx_cpymem(pos, r->headers_out.content_type.data, - r->headers_out.content_type.len); + p = ngx_cpymem(p, r->headers_out.content_type.data, + r->headers_out.content_type.len); - pos = ngx_cpymem(pos, "; charset=", sizeof("; charset=") - 1); + p = ngx_cpymem(p, "; charset=", sizeof("; charset=") - 1); - pos = ngx_cpymem(pos, r->headers_out.charset.data, - r->headers_out.charset.len); + p = ngx_cpymem(p, r->headers_out.charset.data, + r->headers_out.charset.len); - /* update r->headers_out.content_type for possible logging */ + /* updated r->headers_out.content_type is also needed for logging */ - r->headers_out.content_type.len = pos - p; - r->headers_out.content_type.data = p; + r->headers_out.content_type.len = len; + r->headers_out.content_type.data = p - len; + } - } else { - *pos = NGX_HTTP_V2_ENCODE_RAW; - pos = ngx_http_v2_write_int(pos, ngx_http_v2_prefix(7), - r->headers_out.content_type.len); - pos = ngx_cpymem(pos, r->headers_out.content_type.data, - r->headers_out.content_type.len); - } + pos = ngx_http_v2_write_value(pos, r->headers_out.content_type.data, + r->headers_out.content_type.len, tmp); } if (r->headers_out.content_length == NULL @@ -476,26 +500,26 @@ ngx_http_v2_header_filter(ngx_http_reque { *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_LAST_MODIFIED_INDEX); - *pos++ = NGX_HTTP_V2_ENCODE_RAW - | (sizeof("Wed, 31 Dec 1986 18:00:00 GMT") - 1); - pos = ngx_http_time(pos, r->headers_out.last_modified_time); + ngx_http_time(pos, r->headers_out.last_modified_time); + len = sizeof("Wed, 31 Dec 1986 18:00:00 GMT") - 1; + + /* + * Date will always be encoded using huffman in the temporary buffer, + * so it's safe here to use src and dst pointing to the same address. + */ + pos = ngx_http_v2_write_value(pos, pos, len, tmp); } if (r->headers_out.location && r->headers_out.location->value.len) { *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_LOCATION_INDEX); - - *pos = NGX_HTTP_V2_ENCODE_RAW; - pos = ngx_http_v2_write_int(pos, ngx_http_v2_prefix(7), - r->headers_out.location->value.len); - pos = ngx_cpymem(pos, r->headers_out.location->value.data, - r->headers_out.location->value.len); + pos = ngx_http_v2_write_value(pos, r->headers_out.location->value.data, + r->headers_out.location->value.len, tmp); } #if (NGX_HTTP_GZIP) if (r->gzip_vary) { *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_VARY_INDEX); - *pos++ = NGX_HTTP_V2_ENCODE_RAW | (sizeof("Accept-Encoding") - 1); - pos = ngx_cpymem(pos, "Accept-Encoding", sizeof("Accept-Encoding") - 1); + pos = ngx_cpymem(pos, accept_encoding, sizeof(accept_encoding)); } #endif @@ -520,16 +544,11 @@ ngx_http_v2_header_filter(ngx_http_reque *pos++ = 0; - *pos = NGX_HTTP_V2_ENCODE_RAW; - pos = ngx_http_v2_write_int(pos, ngx_http_v2_prefix(7), - header[i].key.len); - ngx_strlow(pos, header[i].key.data, header[i].key.len); - pos += header[i].key.len; + pos = ngx_http_v2_write_name(pos, header[i].key.data, + header[i].key.len, tmp); - *pos = NGX_HTTP_V2_ENCODE_RAW; - pos = ngx_http_v2_write_int(pos, ngx_http_v2_prefix(7), - header[i].value.len); - pos = ngx_cpymem(pos, header[i].value.data, header[i].value.len); + pos = ngx_http_v2_write_value(pos, header[i].value.data, + header[i].value.len, tmp); } frame = ngx_http_v2_create_headers_frame(r, start, pos); @@ -557,6 +576,32 @@ ngx_http_v2_header_filter(ngx_http_reque static u_char * +ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp, + ngx_uint_t lower) +{ + size_t hlen; + + hlen = ngx_http_v2_huff_encode(src, len, tmp, lower); + + if (hlen > 0) { + *dst = NGX_HTTP_V2_ENCODE_HUFF; + dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), hlen); + return ngx_cpymem(dst, tmp, hlen); + } + + *dst = NGX_HTTP_V2_ENCODE_RAW; + dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), len); + + if (lower) { + ngx_strlow(dst, src, len); + return dst + len; + } + + return ngx_cpymem(dst, src, len); +} + + +static u_char * ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, ngx_uint_t value) { if (value < prefix) { diff -r 5fe617f38222 -r ba3c2ca21aa5 src/http/v2/ngx_http_v2_huff_encode.c --- a/src/http/v2/ngx_http_v2_huff_encode.c Thu Feb 11 18:46:46 2016 +0300 +++ b/src/http/v2/ngx_http_v2_huff_encode.c Thu Feb 11 15:35:36 2016 +0300 @@ -2,9 +2,249 @@ /* * Copyright (C) Nginx, Inc. * Copyright (C) Valentin V. Bartenev + * Copyright (C) 2015 Vlad Krasnov */ #include #include #include + + +typedef struct { + uint32_t code; + uint32_t len; +} ngx_http_v2_huff_encode_code_t; + + +static ngx_http_v2_huff_encode_code_t ngx_http_v2_huff_encode_table[256] = +{ + {0x00001ff8, 13}, {0x007fffd8, 23}, {0x0fffffe2, 28}, {0x0fffffe3, 28}, + {0x0fffffe4, 28}, {0x0fffffe5, 28}, {0x0fffffe6, 28}, {0x0fffffe7, 28}, + {0x0fffffe8, 28}, {0x00ffffea, 24}, {0x3ffffffc, 30}, {0x0fffffe9, 28}, + {0x0fffffea, 28}, {0x3ffffffd, 30}, {0x0fffffeb, 28}, {0x0fffffec, 28}, + {0x0fffffed, 28}, {0x0fffffee, 28}, {0x0fffffef, 28}, {0x0ffffff0, 28}, + {0x0ffffff1, 28}, {0x0ffffff2, 28}, {0x3ffffffe, 30}, {0x0ffffff3, 28}, + {0x0ffffff4, 28}, {0x0ffffff5, 28}, {0x0ffffff6, 28}, {0x0ffffff7, 28}, + {0x0ffffff8, 28}, {0x0ffffff9, 28}, {0x0ffffffa, 28}, {0x0ffffffb, 28}, + {0x00000014, 6}, {0x000003f8, 10}, {0x000003f9, 10}, {0x00000ffa, 12}, + {0x00001ff9, 13}, {0x00000015, 6}, {0x000000f8, 8}, {0x000007fa, 11}, + {0x000003fa, 10}, {0x000003fb, 10}, {0x000000f9, 8}, {0x000007fb, 11}, + {0x000000fa, 8}, {0x00000016, 6}, {0x00000017, 6}, {0x00000018, 6}, + {0x00000000, 5}, {0x00000001, 5}, {0x00000002, 5}, {0x00000019, 6}, + {0x0000001a, 6}, {0x0000001b, 6}, {0x0000001c, 6}, {0x0000001d, 6}, + {0x0000001e, 6}, {0x0000001f, 6}, {0x0000005c, 7}, {0x000000fb, 8}, + {0x00007ffc, 15}, {0x00000020, 6}, {0x00000ffb, 12}, {0x000003fc, 10}, + {0x00001ffa, 13}, {0x00000021, 6}, {0x0000005d, 7}, {0x0000005e, 7}, + {0x0000005f, 7}, {0x00000060, 7}, {0x00000061, 7}, {0x00000062, 7}, + {0x00000063, 7}, {0x00000064, 7}, {0x00000065, 7}, {0x00000066, 7}, + {0x00000067, 7}, {0x00000068, 7}, {0x00000069, 7}, {0x0000006a, 7}, + {0x0000006b, 7}, {0x0000006c, 7}, {0x0000006d, 7}, {0x0000006e, 7}, + {0x0000006f, 7}, {0x00000070, 7}, {0x00000071, 7}, {0x00000072, 7}, + {0x000000fc, 8}, {0x00000073, 7}, {0x000000fd, 8}, {0x00001ffb, 13}, + {0x0007fff0, 19}, {0x00001ffc, 13}, {0x00003ffc, 14}, {0x00000022, 6}, + {0x00007ffd, 15}, {0x00000003, 5}, {0x00000023, 6}, {0x00000004, 5}, + {0x00000024, 6}, {0x00000005, 5}, {0x00000025, 6}, {0x00000026, 6}, + {0x00000027, 6}, {0x00000006, 5}, {0x00000074, 7}, {0x00000075, 7}, + {0x00000028, 6}, {0x00000029, 6}, {0x0000002a, 6}, {0x00000007, 5}, + {0x0000002b, 6}, {0x00000076, 7}, {0x0000002c, 6}, {0x00000008, 5}, + {0x00000009, 5}, {0x0000002d, 6}, {0x00000077, 7}, {0x00000078, 7}, + {0x00000079, 7}, {0x0000007a, 7}, {0x0000007b, 7}, {0x00007ffe, 15}, + {0x000007fc, 11}, {0x00003ffd, 14}, {0x00001ffd, 13}, {0x0ffffffc, 28}, + {0x000fffe6, 20}, {0x003fffd2, 22}, {0x000fffe7, 20}, {0x000fffe8, 20}, + {0x003fffd3, 22}, {0x003fffd4, 22}, {0x003fffd5, 22}, {0x007fffd9, 23}, + {0x003fffd6, 22}, {0x007fffda, 23}, {0x007fffdb, 23}, {0x007fffdc, 23}, + {0x007fffdd, 23}, {0x007fffde, 23}, {0x00ffffeb, 24}, {0x007fffdf, 23}, + {0x00ffffec, 24}, {0x00ffffed, 24}, {0x003fffd7, 22}, {0x007fffe0, 23}, + {0x00ffffee, 24}, {0x007fffe1, 23}, {0x007fffe2, 23}, {0x007fffe3, 23}, + {0x007fffe4, 23}, {0x001fffdc, 21}, {0x003fffd8, 22}, {0x007fffe5, 23}, + {0x003fffd9, 22}, {0x007fffe6, 23}, {0x007fffe7, 23}, {0x00ffffef, 24}, + {0x003fffda, 22}, {0x001fffdd, 21}, {0x000fffe9, 20}, {0x003fffdb, 22}, + {0x003fffdc, 22}, {0x007fffe8, 23}, {0x007fffe9, 23}, {0x001fffde, 21}, + {0x007fffea, 23}, {0x003fffdd, 22}, {0x003fffde, 22}, {0x00fffff0, 24}, + {0x001fffdf, 21}, {0x003fffdf, 22}, {0x007fffeb, 23}, {0x007fffec, 23}, + {0x001fffe0, 21}, {0x001fffe1, 21}, {0x003fffe0, 22}, {0x001fffe2, 21}, + {0x007fffed, 23}, {0x003fffe1, 22}, {0x007fffee, 23}, {0x007fffef, 23}, + {0x000fffea, 20}, {0x003fffe2, 22}, {0x003fffe3, 22}, {0x003fffe4, 22}, + {0x007ffff0, 23}, {0x003fffe5, 22}, {0x003fffe6, 22}, {0x007ffff1, 23}, + {0x03ffffe0, 26}, {0x03ffffe1, 26}, {0x000fffeb, 20}, {0x0007fff1, 19}, + {0x003fffe7, 22}, {0x007ffff2, 23}, {0x003fffe8, 22}, {0x01ffffec, 25}, + {0x03ffffe2, 26}, {0x03ffffe3, 26}, {0x03ffffe4, 26}, {0x07ffffde, 27}, + {0x07ffffdf, 27}, {0x03ffffe5, 26}, {0x00fffff1, 24}, {0x01ffffed, 25}, + {0x0007fff2, 19}, {0x001fffe3, 21}, {0x03ffffe6, 26}, {0x07ffffe0, 27}, + {0x07ffffe1, 27}, {0x03ffffe7, 26}, {0x07ffffe2, 27}, {0x00fffff2, 24}, + {0x001fffe4, 21}, {0x001fffe5, 21}, {0x03ffffe8, 26}, {0x03ffffe9, 26}, + {0x0ffffffd, 28}, {0x07ffffe3, 27}, {0x07ffffe4, 27}, {0x07ffffe5, 27}, + {0x000fffec, 20}, {0x00fffff3, 24}, {0x000fffed, 20}, {0x001fffe6, 21}, + {0x003fffe9, 22}, {0x001fffe7, 21}, {0x001fffe8, 21}, {0x007ffff3, 23}, + {0x003fffea, 22}, {0x003fffeb, 22}, {0x01ffffee, 25}, {0x01ffffef, 25}, + {0x00fffff4, 24}, {0x00fffff5, 24}, {0x03ffffea, 26}, {0x007ffff4, 23}, + {0x03ffffeb, 26}, {0x07ffffe6, 27}, {0x03ffffec, 26}, {0x03ffffed, 26}, + {0x07ffffe7, 27}, {0x07ffffe8, 27}, {0x07ffffe9, 27}, {0x07ffffea, 27}, + {0x07ffffeb, 27}, {0x0ffffffe, 28}, {0x07ffffec, 27}, {0x07ffffed, 27}, + {0x07ffffee, 27}, {0x07ffffef, 27}, {0x07fffff0, 27}, {0x03ffffee, 26} +}; + + +/* same as above, but embeds lowercase transformation */ +static ngx_http_v2_huff_encode_code_t ngx_http_v2_huff_encode_table_lc[256] = +{ + {0x00001ff8, 13}, {0x007fffd8, 23}, {0x0fffffe2, 28}, {0x0fffffe3, 28}, + {0x0fffffe4, 28}, {0x0fffffe5, 28}, {0x0fffffe6, 28}, {0x0fffffe7, 28}, + {0x0fffffe8, 28}, {0x00ffffea, 24}, {0x3ffffffc, 30}, {0x0fffffe9, 28}, + {0x0fffffea, 28}, {0x3ffffffd, 30}, {0x0fffffeb, 28}, {0x0fffffec, 28}, + {0x0fffffed, 28}, {0x0fffffee, 28}, {0x0fffffef, 28}, {0x0ffffff0, 28}, + {0x0ffffff1, 28}, {0x0ffffff2, 28}, {0x3ffffffe, 30}, {0x0ffffff3, 28}, + {0x0ffffff4, 28}, {0x0ffffff5, 28}, {0x0ffffff6, 28}, {0x0ffffff7, 28}, + {0x0ffffff8, 28}, {0x0ffffff9, 28}, {0x0ffffffa, 28}, {0x0ffffffb, 28}, + {0x00000014, 6}, {0x000003f8, 10}, {0x000003f9, 10}, {0x00000ffa, 12}, + {0x00001ff9, 13}, {0x00000015, 6}, {0x000000f8, 8}, {0x000007fa, 11}, + {0x000003fa, 10}, {0x000003fb, 10}, {0x000000f9, 8}, {0x000007fb, 11}, + {0x000000fa, 8}, {0x00000016, 6}, {0x00000017, 6}, {0x00000018, 6}, + {0x00000000, 5}, {0x00000001, 5}, {0x00000002, 5}, {0x00000019, 6}, + {0x0000001a, 6}, {0x0000001b, 6}, {0x0000001c, 6}, {0x0000001d, 6}, + {0x0000001e, 6}, {0x0000001f, 6}, {0x0000005c, 7}, {0x000000fb, 8}, + {0x00007ffc, 15}, {0x00000020, 6}, {0x00000ffb, 12}, {0x000003fc, 10}, + {0x00001ffa, 13}, {0x00000003, 5}, {0x00000023, 6}, {0x00000004, 5}, + {0x00000024, 6}, {0x00000005, 5}, {0x00000025, 6}, {0x00000026, 6}, + {0x00000027, 6}, {0x00000006, 5}, {0x00000074, 7}, {0x00000075, 7}, + {0x00000028, 6}, {0x00000029, 6}, {0x0000002a, 6}, {0x00000007, 5}, + {0x0000002b, 6}, {0x00000076, 7}, {0x0000002c, 6}, {0x00000008, 5}, + {0x00000009, 5}, {0x0000002d, 6}, {0x00000077, 7}, {0x00000078, 7}, + {0x00000079, 7}, {0x0000007a, 7}, {0x0000007b, 7}, {0x00001ffb, 13}, + {0x0007fff0, 19}, {0x00001ffc, 13}, {0x00003ffc, 14}, {0x00000022, 6}, + {0x00007ffd, 15}, {0x00000003, 5}, {0x00000023, 6}, {0x00000004, 5}, + {0x00000024, 6}, {0x00000005, 5}, {0x00000025, 6}, {0x00000026, 6}, + {0x00000027, 6}, {0x00000006, 5}, {0x00000074, 7}, {0x00000075, 7}, + {0x00000028, 6}, {0x00000029, 6}, {0x0000002a, 6}, {0x00000007, 5}, + {0x0000002b, 6}, {0x00000076, 7}, {0x0000002c, 6}, {0x00000008, 5}, + {0x00000009, 5}, {0x0000002d, 6}, {0x00000077, 7}, {0x00000078, 7}, + {0x00000079, 7}, {0x0000007a, 7}, {0x0000007b, 7}, {0x00007ffe, 15}, + {0x000007fc, 11}, {0x00003ffd, 14}, {0x00001ffd, 13}, {0x0ffffffc, 28}, + {0x000fffe6, 20}, {0x003fffd2, 22}, {0x000fffe7, 20}, {0x000fffe8, 20}, + {0x003fffd3, 22}, {0x003fffd4, 22}, {0x003fffd5, 22}, {0x007fffd9, 23}, + {0x003fffd6, 22}, {0x007fffda, 23}, {0x007fffdb, 23}, {0x007fffdc, 23}, + {0x007fffdd, 23}, {0x007fffde, 23}, {0x00ffffeb, 24}, {0x007fffdf, 23}, + {0x00ffffec, 24}, {0x00ffffed, 24}, {0x003fffd7, 22}, {0x007fffe0, 23}, + {0x00ffffee, 24}, {0x007fffe1, 23}, {0x007fffe2, 23}, {0x007fffe3, 23}, + {0x007fffe4, 23}, {0x001fffdc, 21}, {0x003fffd8, 22}, {0x007fffe5, 23}, + {0x003fffd9, 22}, {0x007fffe6, 23}, {0x007fffe7, 23}, {0x00ffffef, 24}, + {0x003fffda, 22}, {0x001fffdd, 21}, {0x000fffe9, 20}, {0x003fffdb, 22}, + {0x003fffdc, 22}, {0x007fffe8, 23}, {0x007fffe9, 23}, {0x001fffde, 21}, + {0x007fffea, 23}, {0x003fffdd, 22}, {0x003fffde, 22}, {0x00fffff0, 24}, + {0x001fffdf, 21}, {0x003fffdf, 22}, {0x007fffeb, 23}, {0x007fffec, 23}, + {0x001fffe0, 21}, {0x001fffe1, 21}, {0x003fffe0, 22}, {0x001fffe2, 21}, + {0x007fffed, 23}, {0x003fffe1, 22}, {0x007fffee, 23}, {0x007fffef, 23}, + {0x000fffea, 20}, {0x003fffe2, 22}, {0x003fffe3, 22}, {0x003fffe4, 22}, + {0x007ffff0, 23}, {0x003fffe5, 22}, {0x003fffe6, 22}, {0x007ffff1, 23}, + {0x03ffffe0, 26}, {0x03ffffe1, 26}, {0x000fffeb, 20}, {0x0007fff1, 19}, + {0x003fffe7, 22}, {0x007ffff2, 23}, {0x003fffe8, 22}, {0x01ffffec, 25}, + {0x03ffffe2, 26}, {0x03ffffe3, 26}, {0x03ffffe4, 26}, {0x07ffffde, 27}, + {0x07ffffdf, 27}, {0x03ffffe5, 26}, {0x00fffff1, 24}, {0x01ffffed, 25}, + {0x0007fff2, 19}, {0x001fffe3, 21}, {0x03ffffe6, 26}, {0x07ffffe0, 27}, + {0x07ffffe1, 27}, {0x03ffffe7, 26}, {0x07ffffe2, 27}, {0x00fffff2, 24}, + {0x001fffe4, 21}, {0x001fffe5, 21}, {0x03ffffe8, 26}, {0x03ffffe9, 26}, + {0x0ffffffd, 28}, {0x07ffffe3, 27}, {0x07ffffe4, 27}, {0x07ffffe5, 27}, + {0x000fffec, 20}, {0x00fffff3, 24}, {0x000fffed, 20}, {0x001fffe6, 21}, + {0x003fffe9, 22}, {0x001fffe7, 21}, {0x001fffe8, 21}, {0x007ffff3, 23}, + {0x003fffea, 22}, {0x003fffeb, 22}, {0x01ffffee, 25}, {0x01ffffef, 25}, + {0x00fffff4, 24}, {0x00fffff5, 24}, {0x03ffffea, 26}, {0x007ffff4, 23}, + {0x03ffffeb, 26}, {0x07ffffe6, 27}, {0x03ffffec, 26}, {0x03ffffed, 26}, + {0x07ffffe7, 27}, {0x07ffffe8, 27}, {0x07ffffe9, 27}, {0x07ffffea, 27}, + {0x07ffffeb, 27}, {0x0ffffffe, 28}, {0x07ffffec, 27}, {0x07ffffed, 27}, + {0x07ffffee, 27}, {0x07ffffef, 27}, {0x07fffff0, 27}, {0x03ffffee, 26} +}; + + +#if (NGX_PTR_SIZE == 8) + +#if (NGX_HAVE_LITTLE_ENDIAN) + +#if (NGX_HAVE_GCC_BSWAP64) +#define ngx_http_v2_huff_encode_buf(dst, buf) \ + (*(uint64_t *) (dst) = __builtin_bswap64(buf)) +#else +#define ngx_http_v2_huff_encode_buf(dst, buf) \ + ((dst)[0] = (u_char) ((buf) >> 56), \ + (dst)[1] = (u_char) ((buf) >> 48), \ + (dst)[2] = (u_char) ((buf) >> 40), \ + (dst)[3] = (u_char) ((buf) >> 32), \ + (dst)[4] = (u_char) ((buf) >> 24), \ + (dst)[5] = (u_char) ((buf) >> 16), \ + (dst)[6] = (u_char) ((buf) >> 8), \ + (dst)[7] = (u_char) (buf)) +#endif + +#else /* !NGX_HAVE_LITTLE_ENDIAN */ +#define ngx_http_v2_huff_encode_buf(dst, buf) \ + (*(uint64_t *) (dst) = (buf)) +#endif + +#else /* NGX_PTR_SIZE == 4 */ + +#define ngx_http_v2_huff_encode_buf(dst, buf) \ + (*(uint32_t *) (dst) = htonl(buf)) + +#endif + + +size_t +ngx_http_v2_huff_encode(u_char *src, size_t len, u_char *dst, ngx_uint_t lower) +{ + u_char *end; + size_t hlen; + ngx_uint_t buf, pending, code; + ngx_http_v2_huff_encode_code_t *table, *next; + + table = lower ? ngx_http_v2_huff_encode_table_lc + : ngx_http_v2_huff_encode_table; + hlen = 0; + buf = 0; + pending = 0; + + end = src + len; + + while (src != end) { + next = &table[*src++]; + + code = next->code; + pending += next->len; + + /* accumulate bits */ + if (pending < sizeof(buf) * 8) { + buf |= code << (sizeof(buf) * 8 - pending); + continue; + } + + if (hlen + sizeof(buf) >= len) { + return 0; + } + + pending -= sizeof(buf) * 8; + + buf |= code >> pending; + + ngx_http_v2_huff_encode_buf(&dst[hlen], buf); + + hlen += sizeof(buf); + + buf = pending ? code << (sizeof(buf) * 8 - pending) : 0; + } + + buf |= (ngx_uint_t) -1 >> pending; + + pending = ngx_align(pending, 8); + + if (hlen + pending / 8 >= len) { + return 0; + } + + buf >>= sizeof(buf) * 8 - pending; + + while (pending) { + pending -= 8; + dst[hlen++] = (u_char) (buf >> pending); + } + + return hlen; +} From vbart at nginx.com Thu Feb 11 16:36:13 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Thu, 11 Feb 2016 19:36:13 +0300 Subject: [PATCH] HTTP/2: HPACK Huffman encoding In-Reply-To: <1506160.nyu9cTvipg@vbart-workstation> References: <284F77E2-2D4B-4BE5-A7F8-374C10EE36B4@cloudflare.com> <1506160.nyu9cTvipg@vbart-workstation> Message-ID: <4258129.Ve18Vz54Uk@vbart-workstation> On Friday 22 January 2016 13:53:01 Valentin V. Bartenev wrote: > On Wednesday 20 January 2016 14:01:15 Vlad Krasnov wrote: > > LGTM > > > > Cheers, > > Vlad > > > [..] > > Thank you. The patch will be committed after internal review. > [..] Committed with the changes made during the review: http://hg.nginx.org/nginx/rev/ba3c2ca21aa5 wbr, Valentin V. Bartenev From vlad at cloudflare.com Thu Feb 11 21:38:59 2016 From: vlad at cloudflare.com (Vlad Krasnov) Date: Thu, 11 Feb 2016 13:38:59 -0800 Subject: [PATCH] HTTP/2: HPACK Huffman encoding In-Reply-To: <4258129.Ve18Vz54Uk@vbart-workstation> References: <284F77E2-2D4B-4BE5-A7F8-374C10EE36B4@cloudflare.com> <1506160.nyu9cTvipg@vbart-workstation> <4258129.Ve18Vz54Uk@vbart-workstation> Message-ID: <3796916B-E5F1-4317-B455-5532EF7FC44C@cloudflare.com> I am very happy! Thank you Valentin. Cheers, Vlad > On 11 Feb 2016, at 08:36, Valentin V. Bartenev wrote: > > On Friday 22 January 2016 13:53:01 Valentin V. Bartenev wrote: >> On Wednesday 20 January 2016 14:01:15 Vlad Krasnov wrote: >>> LGTM >>> >>> Cheers, >>> Vlad >>> >> [..] >> >> Thank you. The patch will be committed after internal review. >> > [..] > > Committed with the changes made during the review: > http://hg.nginx.org/nginx/rev/ba3c2ca21aa5 > > wbr, Valentin V. Bartenev > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From agentzh at gmail.com Thu Feb 11 22:03:45 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Thu, 11 Feb 2016 14:03:45 -0800 Subject: Dynamic module search paths? Message-ID: Hi folks It seems to me that the the load_module directive for loading NGINX dynamic modules just use the server prefix when resolving relative module DSO file paths specified in nginx.conf. Here is my wishlist: I hope that we can have support for module search paths specified via an external environment or an nginx command-line option so that nginx.conf can be more portable across different environments. This is particularly useful when distributing various NGINX-based applications where a single NGINX installation can serve multiple different applications with different server prefixes in the same box at the same time. What do you think? Best regards, -agentzh From agentzh at gmail.com Thu Feb 11 22:07:14 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Thu, 11 Feb 2016 14:07:14 -0800 Subject: Already loaded NGINX modules Message-ID: Hi guys! Currently when an NGINX module is statically linked against the NGINX binary, the load_module directive bails out the server startup with the error message "module already loaded" (or something like that). Hopefully we can make this a nonfatal error (or provide an option to make it nonfatal) because we can have more portable nginx.conf for distributing NGINX-based applications. Thanks for your attention! Best regards, -agentzh From agentzh at gmail.com Thu Feb 11 22:10:02 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Thu, 11 Feb 2016 14:10:02 -0800 Subject: Add /etc/hosts support to NGINX's own resolver Message-ID: Hi guys! I wonder if you have any plans or interest in adding support for system hosts configuration files (like /etc/hosts on Linux/*BSD/Mac OS X) to NGINX's own nonblocking resolver implementation. This makes debugging and other sysadmin work much easier otherwise we must set up a local DNS server for special host names to work. Thanks for your attention! Best regards, -agentzh From piotrsikora at google.com Thu Feb 11 22:33:43 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 11 Feb 2016 14:33:43 -0800 Subject: Already loaded NGINX modules In-Reply-To: References: Message-ID: Hey Yichun, > Currently when an NGINX module is statically linked against the NGINX > binary, the load_module directive bails out the server startup with > the error message "module already loaded" (or something like that). > Hopefully we can make this a nonfatal error (or provide an option to > make it nonfatal) because we can have more portable nginx.conf for > distributing NGINX-based applications. I disagree, because this would lead to unexpected behavior (since statically linked module can be slightly different from the dynamic module). Which version should be used at runtime in your non-fatal scenario and why? Best regards, Piotr Sikora From agentzh at gmail.com Thu Feb 11 23:16:24 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Thu, 11 Feb 2016 15:16:24 -0800 Subject: Already loaded NGINX modules In-Reply-To: References: Message-ID: Hello! On Thu, Feb 11, 2016 at 2:33 PM, Piotr Sikora wrote: > I disagree, because this would lead to unexpected behavior (since > statically linked module can be slightly different from the dynamic > module). > > Which version should be used at runtime in your non-fatal scenario and why? We don't have version numbers in the DSO file names anyway :) And we can issue warnings to error.log, even with a high log level. Best regards, -agentzh From agentzh at gmail.com Thu Feb 11 23:19:05 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Thu, 11 Feb 2016 15:19:05 -0800 Subject: Already loaded NGINX modules In-Reply-To: References: Message-ID: Hello! On Thu, Feb 11, 2016 at 3:16 PM, Yichun Zhang (agentzh) wrote: > We don't have version numbers in the DSO file names anyway :) And we > can issue warnings to error.log, even with a high log level. > Or with an explicit option to the load_module directive, as in load_module ngx_http_lua_module.so duplicate=ignore; What about this? Begards, -agentzh Regards, -agentzh From piotrsikora at google.com Thu Feb 11 23:29:20 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 11 Feb 2016 15:29:20 -0800 Subject: Already loaded NGINX modules In-Reply-To: References: Message-ID: Hey Yichun, > Or with an explicit option to the load_module directive, as in > > load_module ngx_http_lua_module.so duplicate=ignore; > > What about this? That doesn't really answer my question: which version (statically linked or dynamic) of the module should we use at runtime if both are present... and why? Best regards, Piotr Sikora From agentzh at gmail.com Fri Feb 12 06:44:55 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Thu, 11 Feb 2016 22:44:55 -0800 Subject: Already loaded NGINX modules In-Reply-To: References: Message-ID: Hello! On Thu, Feb 11, 2016 at 3:29 PM, Piotr Sikora wrote: > > That doesn't really answer my question: which version (statically > linked or dynamic) of the module should we use at runtime if both are > present... and why? > For portable NGINX-based applications, for example, we only want to ensure that some modules are *present*, like ngx_http_lua_module, and we do not care about whether it is linked statically or dynamically. We are only concerned about its presence. If the modules we need are not statically linked, we want to dynamically load them. It's this simple :) I don't think it's reasonable to use a dynamic version of a module if it is already statically linked, is it? Best regards, -agentzh From mdounin at mdounin.ru Fri Feb 12 11:34:14 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Feb 2016 14:34:14 +0300 Subject: Dynamic module search paths? In-Reply-To: References: Message-ID: <20160212113413.GG70672@mdounin.ru> Hello! On Thu, Feb 11, 2016 at 02:03:45PM -0800, Yichun Zhang (agentzh) wrote: > Hi folks > > It seems to me that the the load_module directive for loading NGINX > dynamic modules just use the server prefix when resolving relative > module DSO file paths specified in nginx.conf. > > Here is my wishlist: I hope that we can have support for module search > paths specified via an external environment or an nginx command-line > option so that nginx.conf can be more portable across different > environments. > > This is particularly useful when distributing various NGINX-based > applications where a single NGINX installation can serve multiple > different applications with different server prefixes in the same box > at the same time. > > What do you think? I don't like this idea. We already have two prefixes in nginx, and this is 1 more than it should be. If needed, a symbolic link from prefix can be used to point nginx to appropriate place. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Fri Feb 12 11:42:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 12 Feb 2016 14:42:27 +0300 Subject: Already loaded NGINX modules In-Reply-To: References: Message-ID: <20160212114227.GH70672@mdounin.ru> Hello! On Thu, Feb 11, 2016 at 02:33:43PM -0800, Piotr Sikora wrote: > Hey Yichun, > > > Currently when an NGINX module is statically linked against the NGINX > > binary, the load_module directive bails out the server startup with > > the error message "module already loaded" (or something like that). > > Hopefully we can make this a nonfatal error (or provide an option to > > make it nonfatal) because we can have more portable nginx.conf for > > distributing NGINX-based applications. > > I disagree, because this would lead to unexpected behavior (since > statically linked module can be slightly different from the dynamic > module). > > Which version should be used at runtime in your non-fatal scenario and why? +1. If there is no need to load a module - there should be no load_module directive in the configuration. Everything else is likely to cause confusion. This is very similar to duplicate directives in configuration - and duplicate directives are rejected by nginx, for the same reasons. -- Maxim Dounin http://nginx.org/ From agentzh at gmail.com Fri Feb 12 16:50:25 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Fri, 12 Feb 2016 08:50:25 -0800 Subject: Already loaded NGINX modules In-Reply-To: <20160212114227.GH70672@mdounin.ru> References: <20160212114227.GH70672@mdounin.ru> Message-ID: Hello! On Fri, Feb 12, 2016 at 3:42 AM, Maxim Dounin wrote: > If there is no need to load a module - there should be no > load_module directive in the configuration. Everything else is > likely to cause confusion. The problem is that when we prepare nginx configurations for others, we may have no idea how about how a particular set of modules are built on the user side. > > This is very similar to duplicate directives in configuration - > and duplicate directives are rejected by nginx, for the same > reasons. Not really similar because the nginx configuration writer definitely knows if he uses duplicate directives in his own nginx.conf but he can hardly know how the nginx binary on the user side is built since nginx.conf has no such information nor has a way to detect it in nginx.conf itself. Best regards, -agentzh From agentzh at gmail.com Fri Feb 12 16:54:02 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Fri, 12 Feb 2016 08:54:02 -0800 Subject: Dynamic module search paths? In-Reply-To: <20160212113413.GG70672@mdounin.ru> References: <20160212113413.GG70672@mdounin.ru> Message-ID: Hello! On Fri, Feb 12, 2016 at 3:34 AM, Maxim Dounin wrote: > I don't like this idea. We already have two prefixes in nginx, > and this is 1 more than it should be. > > If needed, a symbolic link from prefix can be used to point nginx > to appropriate place. Thanks for the work-around. But it has the following drawbacks: 1. The portable applications' directories would be tainted by symlink files which are system specific. 2. It won't work on systems lacking symlink support, like on Windows. Okay, if you guys really dislike the idea of configurable module search paths, how about just continuing searching the original installation prefix after searching the current server prefix specified by the -p command-line option fails? As you've said, we already have two prefixes, then let's search both! :) Thanks for your attention. Best regards, -agentzh From vbart at nginx.com Fri Feb 12 22:39:45 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Fri, 12 Feb 2016 22:39:45 +0000 Subject: [nginx] HTTP/2: fixed undefined behavior in ngx_http_v2_huff_enc... Message-ID: details: http://hg.nginx.org/nginx/rev/dcfe355dfda4 branches: changeset: 6396:dcfe355dfda4 user: Valentin Bartenev date: Fri Feb 12 16:36:20 2016 +0300 description: HTTP/2: fixed undefined behavior in ngx_http_v2_huff_encode(). When the "pending" value is zero, the "buf" will be right shifted by the width of its type, which results in undefined behavior. Found by Coverity (CID 1352150). diffstat: src/http/v2/ngx_http_v2_huff_encode.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diffs (27 lines): diff -r ba3c2ca21aa5 -r dcfe355dfda4 src/http/v2/ngx_http_v2_huff_encode.c --- a/src/http/v2/ngx_http_v2_huff_encode.c Thu Feb 11 15:35:36 2016 +0300 +++ b/src/http/v2/ngx_http_v2_huff_encode.c Fri Feb 12 16:36:20 2016 +0300 @@ -231,6 +231,10 @@ ngx_http_v2_huff_encode(u_char *src, siz buf = pending ? code << (sizeof(buf) * 8 - pending) : 0; } + if (pending == 0) { + return hlen; + } + buf |= (ngx_uint_t) -1 >> pending; pending = ngx_align(pending, 8); @@ -241,10 +245,10 @@ ngx_http_v2_huff_encode(u_char *src, siz buf >>= sizeof(buf) * 8 - pending; - while (pending) { + do { pending -= 8; dst[hlen++] = (u_char) (buf >> pending); - } + } while (pending); return hlen; } From piotrsikora at google.com Fri Feb 12 22:55:22 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Fri, 12 Feb 2016 14:55:22 -0800 Subject: [PATCH] Dynamic modules: add as a dependency to "make install" target Message-ID: <4dfe52452f0d343b08b8.1455317722@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1455317648 28800 # Fri Feb 12 14:54:08 2016 -0800 # Node ID 4dfe52452f0d343b08b85089aa5ac98120d67ecc # Parent dcfe355dfda4693ac1f3aa8fb9705812c2485bac Dynamic modules: add as a dependency to "make install" target. Reported by badfiles on GitHub. Signed-off-by: Piotr Sikora diff -r dcfe355dfda4 -r 4dfe52452f0d auto/install --- a/auto/install +++ b/auto/install @@ -105,6 +105,7 @@ manpage: $NGX_OBJS/nginx.8 < $NGX_MAN > \$@ install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \ + modules \ $NGX_INSTALL_PERL_MODULES test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX' From mdounin at mdounin.ru Sat Feb 13 00:48:18 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 13 Feb 2016 03:48:18 +0300 Subject: Dynamic module search paths? In-Reply-To: References: <20160212113413.GG70672@mdounin.ru> Message-ID: <20160213004818.GJ70672@mdounin.ru> Hello! On Fri, Feb 12, 2016 at 08:54:02AM -0800, Yichun Zhang (agentzh) wrote: [...] > Okay, if you guys really dislike the idea of configurable module > search paths, how about just continuing searching the original > installation prefix after searching the current server prefix > specified by the -p command-line option fails? The "-p" switch is to override compiler-time options. No "original" prefix is expected to be used once this option is set. > As you've said, we already have two prefixes, then let's search > both! :) The two prefixes I've talked about are prefix and conf_prefix. And using both is not an option too. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Sat Feb 13 01:00:05 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 13 Feb 2016 04:00:05 +0300 Subject: Already loaded NGINX modules In-Reply-To: References: <20160212114227.GH70672@mdounin.ru> Message-ID: <20160213010005.GK70672@mdounin.ru> Hello! On Fri, Feb 12, 2016 at 08:50:25AM -0800, Yichun Zhang (agentzh) wrote: > Hello! > > On Fri, Feb 12, 2016 at 3:42 AM, Maxim Dounin wrote: > > If there is no need to load a module - there should be no > > load_module directive in the configuration. Everything else is > > likely to cause confusion. > > The problem is that when we prepare nginx configurations for others, > we may have no idea how about how a particular set of modules are > built on the user side. As already pointed out, to properly write a configuration in many cases you have to know not only a set of modules, but also particular module versions. I don't think that what you are trying to do can be solved by introducing some "tolerant loading". Instead, you'll introduce confusion for normal users - and you'll still have the same problem with "configurations for others". > > This is very similar to duplicate directives in configuration - > > and duplicate directives are rejected by nginx, for the same > > reasons. > > Not really similar because the nginx configuration writer definitely > knows if he uses duplicate directives in his own nginx.conf but he can > hardly know how the nginx binary on the user side is built since > nginx.conf has no such information nor has a way to detect it in > nginx.conf itself. The question here is where you draw a line. If you assum that the administrator controls full nginx.conf configuration, but has no idea about modules loaded into nginx installed - well, it's may be not very similar. But if you'll assume that the administrator uses some pre-defined configuration snippets he cannot change - this case becomes exactly the same. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Sat Feb 13 04:25:34 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 13 Feb 2016 07:25:34 +0300 Subject: [PATCH] Dynamic modules: add as a dependency to "make install" target In-Reply-To: <4dfe52452f0d343b08b8.1455317722@piotrsikora.sfo.corp.google.com> References: <4dfe52452f0d343b08b8.1455317722@piotrsikora.sfo.corp.google.com> Message-ID: <20160213042534.GQ70672@mdounin.ru> Hello! On Fri, Feb 12, 2016 at 02:55:22PM -0800, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1455317648 28800 > # Fri Feb 12 14:54:08 2016 -0800 > # Node ID 4dfe52452f0d343b08b85089aa5ac98120d67ecc > # Parent dcfe355dfda4693ac1f3aa8fb9705812c2485bac > Dynamic modules: add as a dependency to "make install" target. > > Reported by badfiles on GitHub. > > Signed-off-by: Piotr Sikora > > diff -r dcfe355dfda4 -r 4dfe52452f0d auto/install > --- a/auto/install > +++ b/auto/install > @@ -105,6 +105,7 @@ manpage: $NGX_OBJS/nginx.8 > < $NGX_MAN > \$@ > > install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \ > + modules \ > $NGX_INSTALL_PERL_MODULES > test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX' We've discussed "make install" problem with Ruslan a couple of days ago, and tend to think that something like this would be a better option: # HG changeset patch # User Maxim Dounin # Date 1455337144 -10800 # Sat Feb 13 07:19:04 2016 +0300 # Node ID d1fc94a6bbecfb2fd59c550c5eebbce0fd4a6500 # Parent 317abf4680eb22d80f5127c55a966366e8ab522b Configure: added "build" targed. The "build" targed introduced to do all build-related tasks, and it is now used in Makefile and in objs/Makefile as a dependency for the "install" targed. In particular, this resolves problems as observed with dynamic modules by people trying to do "make install" without calling "make" first. diff --git a/auto/install b/auto/install --- a/auto/install +++ b/auto/install @@ -104,8 +104,7 @@ manpage: $NGX_OBJS/nginx.8 -e "s|%%ERROR_LOG_PATH%%|${NGX_ERROR_LOG_PATH:-stderr}|" \\ < $NGX_MAN > \$@ -install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \ - $NGX_INSTALL_PERL_MODULES +install: build $NGX_INSTALL_PERL_MODULES test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX' test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \ @@ -187,8 +186,6 @@ cat << END >> Makefile build: \$(MAKE) -f $NGX_MAKEFILE - \$(MAKE) -f $NGX_MAKEFILE modules - \$(MAKE) -f $NGX_MAKEFILE manpage install: \$(MAKE) -f $NGX_MAKEFILE install diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -223,6 +223,8 @@ ngx_main_link=${MAIN_LINK:+`echo $MAIN_L cat << END >> $NGX_MAKEFILE +build: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} modules manpage + $NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link $ngx_rcc -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Sat Feb 13 04:51:18 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 13 Feb 2016 04:51:18 +0000 Subject: [nginx] Win32: simplified and improved handling of MSVC versions. Message-ID: details: http://hg.nginx.org/nginx/rev/78f8ac479735 branches: changeset: 6397:78f8ac479735 user: Maxim Dounin date: Sat Feb 13 06:47:34 2016 +0300 description: Win32: simplified and improved handling of MSVC versions. Now we always set NGX_CC_NAME to "msvc", and additionally test compiler version as reported by "cl" in auto/cc/msvc (the same version is also available via the _MSC_VER define). In particular, this approach allows to properly check for C99 variadic macros support, which previously was not used with MSVC versions not explicitly recognized. Now unneeded wildcards in NGX_CC_NAME tests for msvc removed accordingly, as well as unused wildcards for owc and icc. diffstat: auto/cc/msvc | 31 +++++++++++++++++++++++-------- auto/cc/name | 27 ++------------------------- auto/lib/md5/conf | 4 ++-- auto/lib/md5/make | 4 ++-- auto/lib/pcre/conf | 4 ++-- auto/lib/pcre/make | 4 ++-- auto/lib/sha1/conf | 4 ++-- auto/lib/sha1/make | 4 ++-- auto/lib/zlib/conf | 4 ++-- auto/lib/zlib/make | 4 ++-- 10 files changed, 41 insertions(+), 49 deletions(-) diffs (244 lines): diff --git a/auto/cc/msvc b/auto/cc/msvc --- a/auto/cc/msvc +++ b/auto/cc/msvc @@ -3,9 +3,24 @@ # Copyright (C) Nginx, Inc. -# MSVC 6.0 SP2 -# MSVC Toolkit 2003 (7.1) -# MSVC 2005 Express Edition SP1 (8.0) +# MSVC 6.0 SP2 cl 12.00 +# MSVC Toolkit 2003 (7.1) cl 13.10 +# MSVC 2005 Express Edition SP1 (8.0) cl 14.00 +# MSVC 2008 Express Edition (9.0) cl 15.00 +# MSVC 2010 (10.0) cl 16.00 +# MSVC 2015 (14.0) cl 19.00 + + +NGX_MSVC_VER=`$NGX_WINE $CC 2>&1 | grep 'Compiler Version' 2>&1 \ + | sed -e 's/^.* Version \(.*\)/\1/'` + +echo " + cl version: $NGX_MSVC_VER" + +have=NGX_COMPILER value="\"cl $NGX_MSVC_VER\"" . auto/define + + +ngx_msvc_ver=`echo $NGX_MSVC_VER | sed -e 's/^\([0-9]*\).*/\1/'` + # optimizations @@ -90,17 +105,17 @@ CORE_LIBS="$CORE_LIBS kernel32.lib user3 #CORE_LINK="$CORE_LINK -subsystem:windows -entry:mainCRTStartup" # debug -# msvc8 under Wine issues -# Program database manager mismatch; please check your installation -if [ $NGX_CC_NAME != msvc8 ]; then +# msvc under Wine issues +# C1902: Program database manager mismatch; please check your installation +if [ -z "$NGX_WINE" ]; then CFLAGS="$CFLAGS -Zi" CORE_LINK="$CORE_LINK -debug" fi # MSVC 2005 supports C99 variadic macros -if [ $NGX_CC_NAME = msvc8 ]; then - have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have +if [ "$ngx_msvc_ver" -ge 14 ]; then + have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have fi diff --git a/auto/cc/name b/auto/cc/name --- a/auto/cc/name +++ b/auto/cc/name @@ -25,31 +25,8 @@ fi if [ "$CC" = cl ]; then - if `$NGX_WINE $CC -v 2>&1 \ - | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16' \ - >/dev/null 2>&1`; then - - NGX_CC_NAME=msvc10 - echo " + using Microsoft Visual C++ 10 compiler" - - elif `$NGX_WINE $CC -v 2>&1 \ - | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14' \ - >/dev/null 2>&1`; then - - NGX_CC_NAME=msvc8 - echo " + using Microsoft Visual C++ 8 compiler" - - elif `$NGX_WINE $CC -v 2>&1 \ - | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13' \ - >/dev/null 2>&1`; then - - NGX_CC_NAME=msvc7 - echo " + using Microsoft Visual C++ 7 compiler" - - else - NGX_CC_NAME=msvc - echo " + using Microsoft Visual C++ compiler" - fi + NGX_CC_NAME=msvc + echo " + using Microsoft Visual C++ compiler" elif [ "$CC" = wcl386 ]; then NGX_CC_NAME=owc diff --git a/auto/lib/md5/conf b/auto/lib/md5/conf --- a/auto/lib/md5/conf +++ b/auto/lib/md5/conf @@ -20,12 +20,12 @@ if [ $MD5 != NONE ]; then case "$NGX_CC_NAME" in - msvc* | owc* | bcc) + msvc | owc | bcc) LINK_DEPS="$LINK_DEPS $MD5/md5.lib" CORE_LIBS="$CORE_LIBS $MD5/md5.lib" ;; - icc*) + icc) LINK_DEPS="$LINK_DEPS $MD5/libmd5.a" # to allow -ipo optimization we link with the *.o but not library diff --git a/auto/lib/md5/make b/auto/lib/md5/make --- a/auto/lib/md5/make +++ b/auto/lib/md5/make @@ -5,13 +5,13 @@ case "$NGX_CC_NAME" in - msvc*) + msvc) ngx_makefile=makefile.msvc ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC MD5_ASM=$MD5_ASM" ngx_md5="MD5=\"$MD5\"" ;; - owc*) + owc) ngx_makefile=makefile.owc ngx_opt="CPU_OPT=\"$CPU_OPT\"" ngx_md5=`echo MD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"` diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf --- a/auto/lib/pcre/conf +++ b/auto/lib/pcre/conf @@ -8,7 +8,7 @@ if [ $PCRE != NONE ]; then case "$NGX_CC_NAME" in - msvc* | owc* | bcc) + msvc | owc | bcc) have=NGX_PCRE . auto/have have=PCRE_STATIC . auto/have CORE_DEPS="$CORE_DEPS $PCRE/pcre.h" @@ -16,7 +16,7 @@ if [ $PCRE != NONE ]; then CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib" ;; - icc* ) + icc) have=NGX_PCRE . auto/have CORE_DEPS="$CORE_DEPS $PCRE/pcre.h" diff --git a/auto/lib/pcre/make b/auto/lib/pcre/make --- a/auto/lib/pcre/make +++ b/auto/lib/pcre/make @@ -5,13 +5,13 @@ case "$NGX_CC_NAME" in - msvc*) + msvc) ngx_makefile=makefile.msvc ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC" ngx_pcre="PCRE=\"$PCRE\"" ;; - owc*) + owc) ngx_makefile=makefile.owc ngx_opt="CPU_OPT=\"$CPU_OPT\"" ngx_pcre=`echo PCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"` diff --git a/auto/lib/sha1/conf b/auto/lib/sha1/conf --- a/auto/lib/sha1/conf +++ b/auto/lib/sha1/conf @@ -10,12 +10,12 @@ if [ $SHA1 != NONE ]; then case "$NGX_CC_NAME" in - msvc* | owc* | bcc) + msvc | owc | bcc) LINK_DEPS="$LINK_DEPS $SHA1/sha1.lib" CORE_LIBS="$CORE_LIBS $SHA1/sha1.lib" ;; - icc*) + icc) LINK_DEPS="$LINK_DEPS $SHA1/libsha.a" # to allow -ipo optimization we link with the *.o but not library diff --git a/auto/lib/sha1/make b/auto/lib/sha1/make --- a/auto/lib/sha1/make +++ b/auto/lib/sha1/make @@ -5,13 +5,13 @@ case "$NGX_CC_NAME" in - msvc*) + msvc) ngx_makefile=makefile.msvc ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC SHA1_ASM=$SHA1_ASM" ngx_sha1="SHA1=\"$SHA1\"" ;; - owc*) + owc) ngx_makefile=makefile.owc ngx_opt="CPU_OPT=\"$CPU_OPT\"" ngx_sha1=`echo SHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"` diff --git a/auto/lib/zlib/conf b/auto/lib/zlib/conf --- a/auto/lib/zlib/conf +++ b/auto/lib/zlib/conf @@ -8,13 +8,13 @@ if [ $ZLIB != NONE ]; then case "$NGX_CC_NAME" in - msvc* | owc* | bcc) + msvc | owc | bcc) have=NGX_ZLIB . auto/have LINK_DEPS="$LINK_DEPS $ZLIB/zlib.lib" CORE_LIBS="$CORE_LIBS $ZLIB/zlib.lib" ;; - icc*) + icc) have=NGX_ZLIB . auto/have LINK_DEPS="$LINK_DEPS $ZLIB/libz.a" diff --git a/auto/lib/zlib/make b/auto/lib/zlib/make --- a/auto/lib/zlib/make +++ b/auto/lib/zlib/make @@ -5,14 +5,14 @@ case "$NGX_CC_NAME" in - msvc*) + msvc) ngx_makefile=makefile.msvc ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC" ngx_zlib="ZLIB=\"$ZLIB\"" ;; - owc*) + owc) ngx_makefile=makefile.owc ngx_opt="CPU_OPT=\"$CPU_OPT\"" ngx_zlib=`echo ZLIB=\"$ZLIB\" | sed -e "s/\//$ngx_regex_dirsep/g"` From mdounin at mdounin.ru Sat Feb 13 04:51:20 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 13 Feb 2016 04:51:20 +0000 Subject: [nginx] Updated OpenSSL used for win32 builds. Message-ID: details: http://hg.nginx.org/nginx/rev/c8491e096e13 branches: changeset: 6398:c8491e096e13 user: Maxim Dounin date: Sat Feb 13 07:28:14 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.2e +OPENSSL = openssl-1.0.2f ZLIB = zlib-1.2.8 PCRE = pcre-8.38 From mdounin at mdounin.ru Sat Feb 13 05:29:05 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 13 Feb 2016 08:29:05 +0300 Subject: Proposed changeset to fix client cert from ngx_ssl_get_certificate passed as HTTP header value In-Reply-To: References: <20160204182928.GF70403@mdounin.ru> <20160205155811.GP70403@mdounin.ru> Message-ID: <20160213052904.GS70672@mdounin.ru> Hello! On Wed, Feb 10, 2016 at 02:38:43PM -0800, Sam McKelvie wrote: > OK, sorry for the delay. > > Here is a changeset that implements $ssl_client_escaped_certificate, > following your latest comments. It works well with node/express. OK > with this? See review below. > > ~Sam > > > # HG changeset patch > # User Sam McKelvie > # Date 1455143619 28800 > # Wed Feb 10 14:33:39 2016 -0800 > # Node ID f3f2dbd8340f04adccd805ff5a8547e10e6fa874 > # Parent e0d7c2f718515d4c48e5ed2a0643294da60cf2ba > Define a new $ssl_client_escaped_certificate variable that is the > URL-encoded form of the raw PEM client certificate. This variable > is always appropriate for inclusion in proxy_set_header values, > unlike the $ssl_client_cert variable, which includes '\n' > characters that are not prefixed by '\r', breaking some http > servers (e.g., node/express). > > Per Maxim, $ssl_client_cert should eventually be deprecated. Users > of $ssl_client_cert should move to ssl_client_scaped_certificate. > > Tested with node/express and nginx-tests. This should be rewritten to contain less typos and better match recommended format, see some hints here: http://nginx.org/en/docs/contributing_changes.html Additionally, instead of focusing on badly-written servers which don't handle "\n" you may want to focus on header folding being deprecated in general. > > diff -r e0d7c2f71851 -r f3f2dbd8340f src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c Fri Feb 05 14:02:54 2016 +0300 > +++ b/src/event/ngx_event_openssl.c Wed Feb 10 14:33:39 2016 -0800 > @@ -3273,6 +3273,42 @@ > > > ngx_int_t > +ngx_ssl_get_escaped_certificate(ngx_connection_t *c, ngx_pool_t *pool, > + ngx_str_t *s) Style: function definition/declaration arguments are wrapped with 4-space indent. > +{ > + size_t len; > + ngx_str_t cert; > + uintptr_t escape; > + > + s->data = NULL; > + s->len = 0; These initializations look unneeded. Both s->data and s->len are always set if NGX_OK is returned. > + > + if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) { > + return NGX_ERROR; > + } > + You may want to add (cert.len == 0) special case here, much like in ngx_ssl_get_certificate(). > + escape = ngx_escape_uri(NULL, cert.data, cert.len, > + NGX_ESCAPE_URI_COMPONENT); > + > + /* Each escaped character adds 2 characters to result */ > + len = cert.len + 2 * escape; Just using escape = 2 * ngx_escape_uri(...); or even len = cert.len + 2 * ngx_escape_uri(...); as in other places is much better idea than adding an obvious comment. > + > + s->data = ngx_pnalloc(pool, len); > + if (s->data == NULL) { > + ngx_pfree(pool, cert.data); There is no need to free small/non-recurring allocations from pool. Especially when returning errors - as this usually means that nginx will just terminate the request and will free the pool. > + return NGX_ERROR; > + } > + s->len = len; Something like: s->len = len; s->data = ngx_pnalloc(pool, len); if (s->data == NULL) { return NGX_ERROR; } as in ngx_ssl_get_certificate() should be a bit more readable. > + > + ngx_escape_uri(s->data, cert.data, cert.len, NGX_ESCAPE_URI_COMPONENT); > + > + ngx_pfree(pool, cert.data); There is no need to free small/non-recurring allocations from pool. > + > + return NGX_OK; > +} > + > + > +ngx_int_t > ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) > { > char *p; > diff -r e0d7c2f71851 -r f3f2dbd8340f src/event/ngx_event_openssl.h > --- a/src/event/ngx_event_openssl.h Fri Feb 05 14:02:54 2016 +0300 > +++ b/src/event/ngx_event_openssl.h Wed Feb 10 14:33:39 2016 -0800 > @@ -180,6 +180,8 @@ > ngx_str_t *s); > ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, > ngx_str_t *s); > +ngx_int_t ngx_ssl_get_escaped_certificate(ngx_connection_t *c, > ngx_pool_t *pool, > + ngx_str_t *s); The patch seems to be currupted by your mail client here. > ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, > ngx_str_t *s); > ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, > diff -r e0d7c2f71851 -r f3f2dbd8340f src/http/modules/ngx_http_ssl_module.c > --- a/src/http/modules/ngx_http_ssl_module.c Fri Feb 05 14:02:54 2016 +0300 > +++ b/src/http/modules/ngx_http_ssl_module.c Wed Feb 10 14:33:39 2016 -0800 > @@ -292,6 +292,9 @@ > (uintptr_t) ngx_ssl_get_raw_certificate, > NGX_HTTP_VAR_CHANGEABLE, 0 }, > > + { ngx_string("ssl_client_escaped_cert"), NULL, ngx_http_ssl_variable, > + (uintptr_t) ngx_ssl_get_escaped_certificate, > NGX_HTTP_VAR_CHANGEABLE, 0 }, > + And here. > { ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable, > (uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 }, > [...] -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Mon Feb 15 14:42:49 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 15 Feb 2016 14:42:49 +0000 Subject: [nginx] Core: improved logging on invalid NGINX variable (ticket... Message-ID: details: http://hg.nginx.org/nginx/rev/50fb3fd79f76 branches: changeset: 6399:50fb3fd79f76 user: Maxim Dounin date: Mon Feb 15 17:41:52 2016 +0300 description: Core: improved logging on invalid NGINX variable (ticket #900). diffstat: src/core/nginx.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (16 lines): diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -481,6 +481,12 @@ ngx_add_inherited_sockets(ngx_cycle_t *c } } + if (v != p) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "invalid socket number \"%s\" in " NGINX_VAR + " environment variable, ignoring", v); + } + ngx_inherited = 1; return ngx_set_inherited_sockets(cycle); From vbart at nginx.com Tue Feb 16 14:50:16 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 16 Feb 2016 14:50:16 +0000 Subject: [nginx] HTTP/2: use local pointer instead of r->connection. Message-ID: details: http://hg.nginx.org/nginx/rev/b4c28876d2c3 branches: changeset: 6400:b4c28876d2c3 user: Valentin Bartenev date: Tue Feb 16 17:49:14 2016 +0300 description: HTTP/2: use local pointer instead of r->connection. No functional changes. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (20 lines): diff -r 50fb3fd79f76 -r b4c28876d2c3 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Mon Feb 15 17:41:52 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Tue Feb 16 17:49:14 2016 +0300 @@ -387,14 +387,14 @@ ngx_http_v2_header_filter(ngx_http_reque } if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) { - ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, + ngx_log_error(NGX_LOG_CRIT, fc->log, 0, "too long response header name: \"%V\"", &header[i].key); return NGX_ERROR; } if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) { - ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, + ngx_log_error(NGX_LOG_CRIT, fc->log, 0, "too long response header value: \"%V: %V\"", &header[i].key, &header[i].value); return NGX_ERROR; From vbart at nginx.com Tue Feb 16 14:50:18 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 16 Feb 2016 14:50:18 +0000 Subject: [nginx] HTTP/2: added debug logging of response headers. Message-ID: details: http://hg.nginx.org/nginx/rev/6812ca9a8002 branches: changeset: 6401:6812ca9a8002 user: Valentin Bartenev date: Tue Feb 16 17:49:14 2016 +0300 description: HTTP/2: added debug logging of response headers. Because of HPACK compression it's hard to see what headers are actually sent by the server. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 41 +++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+), 0 deletions(-) diffs (107 lines): diff -r b4c28876d2c3 -r 6812ca9a8002 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Tue Feb 16 17:49:14 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Tue Feb 16 17:49:14 2016 +0300 @@ -421,6 +421,10 @@ ngx_http_v2_header_filter(ngx_http_reque start = pos; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \":status: %03ui\"", + r->headers_out.status); + if (status) { *pos++ = status; @@ -431,6 +435,10 @@ ngx_http_v2_header_filter(ngx_http_reque } if (r->headers_out.server == NULL) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"server: %s\"", + clcf->server_tokens ? NGINX_VER : "nginx"); + *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX); if (clcf->server_tokens) { @@ -448,6 +456,10 @@ ngx_http_v2_header_filter(ngx_http_reque } if (r->headers_out.date == NULL) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"date: %V\"", + &ngx_cached_http_time); + *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_DATE_INDEX); pos = ngx_http_v2_write_value(pos, ngx_cached_http_time.data, ngx_cached_http_time.len, tmp); @@ -481,6 +493,10 @@ ngx_http_v2_header_filter(ngx_http_reque r->headers_out.content_type.data = p - len; } + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"content-type: %V\"", + &r->headers_out.content_type); + pos = ngx_http_v2_write_value(pos, r->headers_out.content_type.data, r->headers_out.content_type.len, tmp); } @@ -488,6 +504,10 @@ ngx_http_v2_header_filter(ngx_http_reque if (r->headers_out.content_length == NULL && r->headers_out.content_length_n >= 0) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"content-length: %O\"", + r->headers_out.content_length_n); + *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_CONTENT_LENGTH_INDEX); p = pos; @@ -503,6 +523,10 @@ ngx_http_v2_header_filter(ngx_http_reque ngx_http_time(pos, r->headers_out.last_modified_time); len = sizeof("Wed, 31 Dec 1986 18:00:00 GMT") - 1; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"last-modified: %*s\"", + len, pos); + /* * Date will always be encoded using huffman in the temporary buffer, * so it's safe here to use src and dst pointing to the same address. @@ -511,6 +535,10 @@ ngx_http_v2_header_filter(ngx_http_reque } if (r->headers_out.location && r->headers_out.location->value.len) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"location: %V\"", + &r->headers_out.location->value); + *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_LOCATION_INDEX); pos = ngx_http_v2_write_value(pos, r->headers_out.location->value.data, r->headers_out.location->value.len, tmp); @@ -518,6 +546,9 @@ ngx_http_v2_header_filter(ngx_http_reque #if (NGX_HTTP_GZIP) if (r->gzip_vary) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"vary: Accept-Encoding\""); + *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_VARY_INDEX); pos = ngx_cpymem(pos, accept_encoding, sizeof(accept_encoding)); } @@ -542,6 +573,16 @@ ngx_http_v2_header_filter(ngx_http_reque continue; } +#if (NGX_DEBUG) + if (fc->log->log_level & NGX_LOG_DEBUG_HTTP) { + ngx_strlow(tmp, header[i].key.data, header[i].key.len); + + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"%*s: %V\"", + header[i].key.len, tmp, &header[i].value); + } +#endif + *pos++ = 0; pos = ngx_http_v2_write_name(pos, header[i].key.data, From takahiro.kujirai at it.zeus-enterprise.co.jp Wed Feb 17 08:07:12 2016 From: takahiro.kujirai at it.zeus-enterprise.co.jp (Takahiro Kujirai) Date: Wed, 17 Feb 2016 17:07:12 +0900 (JST) Subject: "nginx -v" outputs is in stderr. Message-ID: <58108.153.224.73.205.1455696432.squirrel@www.info.zeus-enterprise.co.jp> Hi all, This is Takahiro Kujirai. When I typed "nginx -v > /tmp/nginx.txt" on nginx 1.9.11, I found output is in stderr. ------- [root at localhost ~]# nginx -v > /tmp/nginx.txt nginx version: nginx/1.9.11 [root at localhost ~]# [root at localhost ~]# nginx -v 2> /tmp/nginx.txt [root at localhost ~]# cat /tmp/nginx.txt nginx version: nginx/1.9.11 I read source code(line374-434 of https://github.com/nginx/nginx/blob/master/src/core/nginx.c), I found using ngx_write_stderr. ------- static void ngx_show_version_info() { ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED); if (ngx_show_help) { ngx_write_stderr( "Usage: nginx [-?hvVtTq] [-s signal] [-c filename] " "[-p prefix] [-g directives]" NGX_LINEFEED NGX_LINEFEED "Options:" NGX_LINEFEED " -?,-h : this help" NGX_LINEFEED " -v : show version and exit" NGX_LINEFEED " -V : show version and configure options then exit" NGX_LINEFEED " -t : test configuration and exit" NGX_LINEFEED " -T : test configuration, dump it and exit" NGX_LINEFEED " -q : suppress non-error messages " "during configuration testing" NGX_LINEFEED " -s signal : send signal to a master process: " "stop, quit, reopen, reload" NGX_LINEFEED #ifdef NGX_PREFIX " -p prefix : set prefix path (default: " NGX_PREFIX ")" NGX_LINEFEED #else " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED #endif " -c filename : set configuration file (default: " NGX_CONF_PATH ")" NGX_LINEFEED " -g directives : set global directives out of configuration " "file" NGX_LINEFEED NGX_LINEFEED ); } if (ngx_show_configure) { #ifdef NGX_COMPILER ngx_write_stderr("built by " NGX_COMPILER NGX_LINEFEED); #endif #if (NGX_SSL) if (SSLeay() == SSLEAY_VERSION_NUMBER) { ngx_write_stderr("built with " OPENSSL_VERSION_TEXT NGX_LINEFEED); } else { ngx_write_stderr("built with " OPENSSL_VERSION_TEXT " (running with "); ngx_write_stderr((char *) (uintptr_t) SSLeay_version(SSLEAY_VERSION)); ngx_write_stderr(")" NGX_LINEFEED); } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME ngx_write_stderr("TLS SNI support enabled" NGX_LINEFEED); #else ngx_write_stderr("TLS SNI support disabled" NGX_LINEFEED); #endif #endif ngx_write_stderr("configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } } I think "stdout" is good, not "stderr", is this the design? And I created patch for this problem. ------- [root at localhost ~]# diff -u ./src/core/nginx.c ./src2/core/nginx.c --- ./src/core/nginx.c2016-02-10 22:56:57.915997223 +0900 +++ ./src2/core/nginx.c2016-02-09 23:11:57.000000000 +0900 @@ -374,10 +374,10 @@ static void ngx_show_version_info() { - ngx_write_stdout("nginx version: " NGINX_VER_BUILD NGX_LINEFEED); + ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED); if (ngx_show_help) { - ngx_write_stdout( + ngx_write_stderr( "Usage: nginx [-?hvVtTq] [-s signal] [-c filename] " "[-p prefix] [-g directives]" NGX_LINEFEED NGX_LINEFEED @@ -409,27 +409,27 @@ if (ngx_show_configure) { #ifdef NGX_COMPILER - ngx_write_stdout("built by " NGX_COMPILER NGX_LINEFEED); + ngx_write_stderr("built by " NGX_COMPILER NGX_LINEFEED); #endif #if (NGX_SSL) if (SSLeay() == SSLEAY_VERSION_NUMBER) { - ngx_write_stdout("built with " OPENSSL_VERSION_TEXT NGX_LINEFEED); + ngx_write_stderr("built with " OPENSSL_VERSION_TEXT NGX_LINEFEED); } else { - ngx_write_stdout("built with " OPENSSL_VERSION_TEXT + ngx_write_stderr("built with " OPENSSL_VERSION_TEXT " (running with "); - ngx_write_stdout((char *) (uintptr_t) + ngx_write_stderr((char *) (uintptr_t) SSLeay_version(SSLEAY_VERSION)); - ngx_write_stdout(")" NGX_LINEFEED); + ngx_write_stderr(")" NGX_LINEFEED); } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - ngx_write_stdout("TLS SNI support enabled" NGX_LINEFEED); + ngx_write_stderr("TLS SNI support enabled" NGX_LINEFEED); #else - ngx_write_stdout("TLS SNI support disabled" NGX_LINEFEED); + ngx_write_stderr("TLS SNI support disabled" NGX_LINEFEED); #endif #endif - ngx_write_stdout("configure arguments:" NGX_CONFIGURE NGX_LINEFEED); + ngx_write_stderr("configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } } Best Regards, Takahiro Kujirai @Zeus-Enterprise.Co.Ltd From mberkvens at synedge.com Wed Feb 17 09:20:37 2016 From: mberkvens at synedge.com (Martijn Berkvens) Date: Wed, 17 Feb 2016 09:20:37 +0000 Subject: Slice module Message-ID: <16B0B0D7-0DD0-4F04-A837-503BCABC629E@synedge.com> Hi, First off, thank you for the work on the slice module. We?re currently using a lua implementation to achieve something similar but this has its shortcomings and we would prefer to use this module. We?ve been testing this module and when using range requests it works as expected, but when doing normal requests (without a request range) the module still slices the content when the configured slice size is met resulting in corrupt data as it will only serve out the configured slice size and not the entire requested file. We run into these issues because a server or location configuration within nginx would service both normal requests as range requests and we have files exceeding the slice size in both cases. Ideally the slice module would only do its magic when a request contains $http_range. We?ve tried creating a map which would set the slice size to 0 (to disable slicing) when no $http_range is present, but unfortunately the slice directive currently does not support variables. For our use case it would most likely be sufficient to add variable support to the slice directive. It is understood and acceptable that we would have duplicate cached content in cases where we have both the sliced versions of the file as the entire file. Thanks again! Regards, Martijn From mdounin at mdounin.ru Wed Feb 17 14:27:13 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 17 Feb 2016 17:27:13 +0300 Subject: "nginx -v" outputs is in stderr. In-Reply-To: <58108.153.224.73.205.1455696432.squirrel@www.info.zeus-enterprise.co.jp> References: <58108.153.224.73.205.1455696432.squirrel@www.info.zeus-enterprise.co.jp> Message-ID: <20160217142713.GY34421@mdounin.ru> Hello! On Wed, Feb 17, 2016 at 05:07:12PM +0900, Takahiro Kujirai wrote: > This is Takahiro Kujirai. > > When I typed "nginx -v > /tmp/nginx.txt" on nginx 1.9.11, I found output > is in stderr. [...] > I think "stdout" is good, not "stderr", is this the design? Yes, this is by design. See https://trac.nginx.org/nginx/ticket/592 for more details. -- Maxim Dounin http://nginx.org/ From takahiro.kujirai at it.zeus-enterprise.co.jp Thu Feb 18 01:59:38 2016 From: takahiro.kujirai at it.zeus-enterprise.co.jp (ZEUS-mgtGM KUJIRAI, Takahiro) Date: Thu, 18 Feb 2016 10:59:38 +0900 (JST) Subject: "nginx -v" outputs is in stderr. Message-ID: <52314.153.224.73.205.1455760778.squirrel@www.info.zeus-enterprise.co.jp> Hello, Dounin! >Yes, this is by design. >See https://trac.nginx.org/nginx/ticket/592 for more details. I understood. And, I like stdout, I'll change source codes and use nginx. Thanks. Takahiro Kujirai @Zeus-Enterprise.Co.Ltd From vl at nginx.com Thu Feb 18 11:11:18 2016 From: vl at nginx.com (Vladimir Homutov) Date: Thu, 18 Feb 2016 11:11:18 +0000 Subject: [nginx] Core: added support for more than 64 CPUs in worker_cpu_... Message-ID: details: http://hg.nginx.org/nginx/rev/7296b38f6416 branches: changeset: 6402:7296b38f6416 user: Vladimir Homutov date: Thu Feb 18 13:58:49 2016 +0300 description: Core: added support for more than 64 CPUs in worker_cpu_affinity. diffstat: src/core/nginx.c | 73 ++++++++++++++++++++++++++-------------- src/core/ngx_cycle.h | 4 +- src/os/unix/ngx_process_cycle.c | 2 +- src/os/unix/ngx_setaffinity.c | 46 ++++++++----------------- src/os/unix/ngx_setaffinity.h | 16 ++++++++- src/os/win32/ngx_process.h | 3 + 6 files changed, 84 insertions(+), 60 deletions(-) diffs (304 lines): diff -r 6812ca9a8002 -r 7296b38f6416 src/core/nginx.c --- a/src/core/nginx.c Tue Feb 16 17:49:14 2016 +0300 +++ b/src/core/nginx.c Thu Feb 18 13:58:49 2016 +0300 @@ -1270,16 +1270,16 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx #if (NGX_HAVE_CPU_AFFINITY) ngx_core_conf_t *ccf = conf; - u_char ch; - uint64_t *mask; + u_char ch, *p; ngx_str_t *value; ngx_uint_t i, n; + ngx_cpuset_t *mask; if (ccf->cpu_affinity) { return "is duplicate"; } - mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t)); + mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(ngx_cpuset_t)); if (mask == NULL) { return NGX_CONF_ERROR; } @@ -1299,7 +1299,12 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx } ccf->cpu_affinity_auto = 1; - mask[0] = (uint64_t) -1 >> (64 - ngx_min(64, ngx_ncpu)); + + CPU_ZERO(&mask[0]); + for (i = 0; i < (ngx_uint_t) ngx_min(ngx_ncpu, CPU_SETSIZE); i++) { + CPU_SET(i, &mask[0]); + } + n = 2; } else { @@ -1308,30 +1313,34 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx for ( /* void */ ; n < cf->args->nelts; n++) { - if (value[n].len > 64) { + if (value[n].len > CPU_SETSIZE) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"worker_cpu_affinity\" supports up to 64 CPUs only"); + "\"worker_cpu_affinity\" supports up to %d CPUs only", + CPU_SETSIZE); return NGX_CONF_ERROR; } - mask[n - 1] = 0; + i = 0; + CPU_ZERO(&mask[n - 1]); - for (i = 0; i < value[n].len; i++) { - - ch = value[n].data[i]; + for (p = value[n].data + value[n].len - 1; + p >= value[n].data; + p--) + { + ch = *p; if (ch == ' ') { continue; } - mask[n - 1] <<= 1; + i++; if (ch == '0') { continue; } if (ch == '1') { - mask[n - 1] |= 1; + CPU_SET(i - 1, &mask[n - 1]); continue; } @@ -1353,43 +1362,57 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx } -uint64_t +ngx_cpuset_t * ngx_get_cpu_affinity(ngx_uint_t n) { - uint64_t mask; - ngx_uint_t i; +#if (NGX_HAVE_CPU_AFFINITY) + ngx_uint_t i, j; + ngx_cpuset_t *mask; ngx_core_conf_t *ccf; + static ngx_cpuset_t result; + ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, ngx_core_module); if (ccf->cpu_affinity == NULL) { - return 0; + return NULL; } if (ccf->cpu_affinity_auto) { - mask = ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; + mask = &ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; - if (mask == 0) { - return 0; - } + for (i = 0, j = n; /* void */ ; i++) { - for (i = 0; /* void */ ; i++) { - if ((mask & ((uint64_t) 1 << (i % 64))) && n-- == 0) { + if (CPU_ISSET(i % CPU_SETSIZE, mask) && j-- == 0) { break; } + if (i == CPU_SETSIZE && j == n) { + /* empty mask */ + return NULL; + } + /* void */ } - return (uint64_t) 1 << (i % 64); + CPU_ZERO(&result); + CPU_SET(i % CPU_SETSIZE, &result); + + return &result; } if (ccf->cpu_affinity_n > n) { - return ccf->cpu_affinity[n]; + return &ccf->cpu_affinity[n]; } - return ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; + return &ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; + +#else + + return NULL; + +#endif } diff -r 6812ca9a8002 -r 7296b38f6416 src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Tue Feb 16 17:49:14 2016 +0300 +++ b/src/core/ngx_cycle.h Thu Feb 18 13:58:49 2016 +0300 @@ -94,7 +94,7 @@ typedef struct { ngx_uint_t cpu_affinity_auto; ngx_uint_t cpu_affinity_n; - uint64_t *cpu_affinity; + ngx_cpuset_t *cpu_affinity; char *username; ngx_uid_t user; @@ -121,7 +121,7 @@ ngx_int_t ngx_signal_process(ngx_cycle_t void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user); char **ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last); ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv); -uint64_t ngx_get_cpu_affinity(ngx_uint_t n); +ngx_cpuset_t *ngx_get_cpu_affinity(ngx_uint_t n); ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag); diff -r 6812ca9a8002 -r 7296b38f6416 src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c Tue Feb 16 17:49:14 2016 +0300 +++ b/src/os/unix/ngx_process_cycle.c Thu Feb 18 13:58:49 2016 +0300 @@ -784,9 +784,9 @@ static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker) { sigset_t set; - uint64_t cpu_affinity; ngx_int_t n; ngx_uint_t i; + ngx_cpuset_t *cpu_affinity; struct rlimit rlmt; ngx_core_conf_t *ccf; ngx_listening_t *ls; diff -r 6812ca9a8002 -r 7296b38f6416 src/os/unix/ngx_setaffinity.c --- a/src/os/unix/ngx_setaffinity.c Tue Feb 16 17:49:14 2016 +0300 +++ b/src/os/unix/ngx_setaffinity.c Thu Feb 18 13:58:49 2016 +0300 @@ -10,29 +10,20 @@ #if (NGX_HAVE_CPUSET_SETAFFINITY) -#include - void -ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log) +ngx_setaffinity(ngx_cpuset_t *cpu_affinity, ngx_log_t *log) { - cpuset_t mask; ngx_uint_t i; - ngx_log_error(NGX_LOG_NOTICE, log, 0, - "cpuset_setaffinity(0x%08Xl)", cpu_affinity); - - CPU_ZERO(&mask); - i = 0; - do { - if (cpu_affinity & 1) { - CPU_SET(i, &mask); + for (i = 0; i < CPU_SETSIZE; i++) { + if (CPU_ISSET(i, cpu_affinity)) { + ngx_log_error(NGX_LOG_NOTICE, log, 0, + "cpuset_setaffinity(): using cpu #%ui", i); } - i++; - cpu_affinity >>= 1; - } while (cpu_affinity); + } if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, - sizeof(cpuset_t), &mask) == -1) + sizeof(cpuset_t), cpu_affinity) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "cpuset_setaffinity() failed"); @@ -42,25 +33,18 @@ ngx_setaffinity(uint64_t cpu_affinity, n #elif (NGX_HAVE_SCHED_SETAFFINITY) void -ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log) +ngx_setaffinity(ngx_cpuset_t *cpu_affinity, ngx_log_t *log) { - cpu_set_t mask; ngx_uint_t i; - ngx_log_error(NGX_LOG_NOTICE, log, 0, - "sched_setaffinity(0x%08Xl)", cpu_affinity); + for (i = 0; i < CPU_SETSIZE; i++) { + if (CPU_ISSET(i, cpu_affinity)) { + ngx_log_error(NGX_LOG_NOTICE, log, 0, + "sched_setaffinity(): using cpu #%ui", i); + } + } - CPU_ZERO(&mask); - i = 0; - do { - if (cpu_affinity & 1) { - CPU_SET(i, &mask); - } - i++; - cpu_affinity >>= 1; - } while (cpu_affinity); - - if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) { + if (sched_setaffinity(0, sizeof(cpu_set_t), cpu_affinity) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "sched_setaffinity() failed"); } diff -r 6812ca9a8002 -r 7296b38f6416 src/os/unix/ngx_setaffinity.h --- a/src/os/unix/ngx_setaffinity.h Tue Feb 16 17:49:14 2016 +0300 +++ b/src/os/unix/ngx_setaffinity.h Thu Feb 18 13:58:49 2016 +0300 @@ -11,12 +11,26 @@ #define NGX_HAVE_CPU_AFFINITY 1 -void ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log); +#if (NGX_HAVE_SCHED_SETAFFINITY) + +typedef cpu_set_t ngx_cpuset_t; + +#elif (NGX_HAVE_CPUSET_SETAFFINITY) + +#include + +typedef cpuset_t ngx_cpuset_t; + +#endif + +void ngx_setaffinity(ngx_cpuset_t *cpu_affinity, ngx_log_t *log); #else #define ngx_setaffinity(cpu_affinity, log) +typedef uint64_t ngx_cpuset_t; + #endif diff -r 6812ca9a8002 -r 7296b38f6416 src/os/win32/ngx_process.h --- a/src/os/win32/ngx_process.h Tue Feb 16 17:49:14 2016 +0300 +++ b/src/os/win32/ngx_process.h Thu Feb 18 13:58:49 2016 +0300 @@ -21,6 +21,9 @@ typedef DWORD ngx_pid_t; (sizeof("ngx_cache_manager_mutex_") + NGX_INT32_LEN) +typedef uint64_t ngx_cpuset_t; + + typedef struct { HANDLE handle; ngx_pid_t pid; From ru at nginx.com Thu Feb 18 14:43:54 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 18 Feb 2016 14:43:54 +0000 Subject: [nginx] Configure: fixed static nginx build with OpenSSL (ticket #903). Message-ID: details: http://hg.nginx.org/nginx/rev/e59e617f8fcb branches: changeset: 6403:e59e617f8fcb user: Ruslan Ermilov date: Thu Feb 18 11:39:57 2016 +0300 description: Configure: fixed static nginx build with OpenSSL (ticket #903). Before 7142b04337d6, it was possible to build the OpenSSL library along with nginx, and link nginx statically with this library (--with-openssl=DIR --with-ld-opt=-static --with-http_ssl_module). This was broken on Linux by not adding -ldl after -lcrypto. The fix also makes it possible to link nginx statically on Linux with the system OpenSSL library, which never worked before. diffstat: auto/lib/openssl/conf | 15 ++++++++------- auto/unix | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diffs (67 lines): diff -r 7296b38f6416 -r e59e617f8fcb auto/lib/openssl/conf --- a/auto/lib/openssl/conf Thu Feb 18 13:58:49 2016 +0300 +++ b/auto/lib/openssl/conf Thu Feb 18 11:39:57 2016 +0300 @@ -32,6 +32,7 @@ if [ $OPENSSL != NONE ]; then CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h" CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a" CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a" + CORE_LIBS="$CORE_LIBS $NGX_LIBDL" if [ "$NGX_PLATFORM" = win32 ]; then CORE_LIBS="$CORE_LIBS -lgdi32 -lcrypt32 -lws2_32" @@ -50,7 +51,7 @@ else ngx_feature_run=no ngx_feature_incs="#include " ngx_feature_path= - ngx_feature_libs="-lssl -lcrypto" + ngx_feature_libs="-lssl -lcrypto $NGX_LIBDL" ngx_feature_test="SSL_library_init()" . auto/feature @@ -62,9 +63,9 @@ else ngx_feature_path="/usr/local/include" if [ $NGX_RPATH = YES ]; then - ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto" + ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto $NGX_LIBDL" else - ngx_feature_libs="-L/usr/local/lib -lssl -lcrypto" + ngx_feature_libs="-L/usr/local/lib -lssl -lcrypto $NGX_LIBDL" fi . auto/feature @@ -78,9 +79,9 @@ else ngx_feature_path="/usr/pkg/include" if [ $NGX_RPATH = YES ]; then - ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lssl -lcrypto" + ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lssl -lcrypto $NGX_LIBDL" else - ngx_feature_libs="-L/usr/pkg/lib -lssl -lcrypto" + ngx_feature_libs="-L/usr/pkg/lib -lssl -lcrypto $NGX_LIBDL" fi . auto/feature @@ -94,9 +95,9 @@ else ngx_feature_path="/opt/local/include" if [ $NGX_RPATH = YES ]; then - ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lssl -lcrypto" + ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lssl -lcrypto $NGX_LIBDL" else - ngx_feature_libs="-L/opt/local/lib -lssl -lcrypto" + ngx_feature_libs="-L/opt/local/lib -lssl -lcrypto $NGX_LIBDL" fi . auto/feature diff -r 7296b38f6416 -r e59e617f8fcb auto/unix --- a/auto/unix Thu Feb 18 13:58:49 2016 +0300 +++ b/auto/unix Thu Feb 18 11:39:57 2016 +0300 @@ -272,6 +272,7 @@ if [ $ngx_found != yes ]; then if [ $ngx_found = yes ]; then CORE_LIBS="$CORE_LIBS -ldl" + NGX_LIBDL="-ldl" fi fi From arut at nginx.com Thu Feb 18 17:14:18 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Thu, 18 Feb 2016 20:14:18 +0300 Subject: Slice module In-Reply-To: <16B0B0D7-0DD0-4F04-A837-503BCABC629E@synedge.com> References: <16B0B0D7-0DD0-4F04-A837-503BCABC629E@synedge.com> Message-ID: <20160218171418.GB13730@Romans-MacBook-Air.local> Hi Martijn, On Wed, Feb 17, 2016 at 09:20:37AM +0000, Martijn Berkvens wrote: > Hi, > > First off, thank you for the work on the slice module. We?re currently using a lua implementation to achieve something similar but this has its shortcomings and we would prefer to use this module. > > We?ve been testing this module and when using range requests it works as expected, but when doing normal requests (without a request range) the module still slices the content when the configured slice size is met resulting in corrupt data as it will only serve out the configured slice size and not the entire requested file. Module slices all requests, whether they have Range header or not. This lets nginx reuse already cached slices. Please describe in detail what exactly is corrupted and show your configuration. Nothing should be corrupted when using the slice module, the entire file should be assembled of slices and sent to client once you configured nginx correctly. > We run into these issues because a server or location configuration within nginx would service both normal requests as range requests and we have files exceeding the slice size in both cases. > > Ideally the slice module would only do its magic when a request contains $http_range. We?ve tried creating a map which would set the slice size to 0 (to disable slicing) when no $http_range is present, but unfortunately the slice directive currently does not support variables. > > For our use case it would most likely be sufficient to add variable support to the slice directive. It is understood and acceptable that we would have duplicate cached content in cases where we have both the sliced versions of the file as the entire file. You can have that by adding another location for files cached as a whole and rewriting your request to that location when $http_range is empty. -- Roman Arutyunyan From pluknet at nginx.com Fri Feb 19 10:33:17 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Fri, 19 Feb 2016 10:33:17 +0000 Subject: [nginx] Configure: skip building OpenSSL documentation to conserve time. Message-ID: details: http://hg.nginx.org/nginx/rev/09d5a22c76bd branches: changeset: 6404:09d5a22c76bd user: Sergey Kandaurov date: Fri Feb 19 13:31:55 2016 +0300 description: Configure: skip building OpenSSL documentation to conserve time. The install_sw target first appeared in OpenSSL 0.9.7e and is documented since OpenSSL 1.0.0 as the way to install the OpenSSL software without documentation. diffstat: auto/lib/openssl/make | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r e59e617f8fcb -r 09d5a22c76bd auto/lib/openssl/make --- a/auto/lib/openssl/make Thu Feb 18 11:39:57 2016 +0300 +++ b/auto/lib/openssl/make Fri Feb 19 13:31:55 2016 +0300 @@ -53,7 +53,7 @@ END && if [ -f Makefile ]; then \$(MAKE) clean; fi \\ && ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\ && \$(MAKE) \\ - && \$(MAKE) install LIBDIR=lib + && \$(MAKE) install_sw LIBDIR=lib END From ru at nginx.com Fri Feb 19 13:29:37 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 19 Feb 2016 13:29:37 +0000 Subject: [nginx] Headers filter: fixed "add_header ... '' always". Message-ID: details: http://hg.nginx.org/nginx/rev/5dfc63c1d9ca branches: changeset: 6405:5dfc63c1d9ca user: Ruslan Ermilov date: Thu Feb 18 15:49:11 2016 +0300 description: Headers filter: fixed "add_header ... '' always". The "always" parameter was ignored if the header value was empty. diffstat: src/http/modules/ngx_http_headers_filter_module.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diffs (29 lines): diff -r 09d5a22c76bd -r 5dfc63c1d9ca src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c Fri Feb 19 13:31:55 2016 +0300 +++ b/src/http/modules/ngx_http_headers_filter_module.c Thu Feb 18 15:49:11 2016 +0300 @@ -712,17 +712,17 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx if (value[2].len == 0) { ngx_memzero(&hv->value, sizeof(ngx_http_complex_value_t)); - return NGX_CONF_OK; - } - ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + } else { + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); - ccv.cf = cf; - ccv.value = &value[2]; - ccv.complex_value = &hv->value; + ccv.cf = cf; + ccv.value = &value[2]; + ccv.complex_value = &hv->value; - if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { - return NGX_CONF_ERROR; + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } } if (cf->args->nelts == 3) { From mdounin at mdounin.ru Fri Feb 19 15:13:45 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 19 Feb 2016 15:13:45 +0000 Subject: [nginx] SSL: fixed SSL_shutdown() comment. Message-ID: details: http://hg.nginx.org/nginx/rev/d194cad6dd3a branches: changeset: 6406:d194cad6dd3a user: Maxim Dounin date: Fri Feb 19 17:27:23 2016 +0300 description: SSL: fixed SSL_shutdown() comment. 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 @@ -1797,7 +1797,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) sslerr = 0; - /* SSL_shutdown() never returns -1, on error it returns 0 */ + /* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */ if (n != 1 && ERR_peek_error()) { sslerr = SSL_get_error(c->ssl->connection, n); From mdounin at mdounin.ru Fri Feb 19 15:13:48 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 19 Feb 2016 15:13:48 +0000 Subject: [nginx] SSL: avoid calling SSL_shutdown() during handshake (ticket #901). Message-ID: details: http://hg.nginx.org/nginx/rev/062c189fee20 branches: changeset: 6407:062c189fee20 user: Maxim Dounin date: Fri Feb 19 17:27:30 2016 +0300 description: SSL: avoid calling SSL_shutdown() during handshake (ticket #901). This fixes "called a function you should not call" and "shutdown while in init" errors as observed with OpenSSL 1.0.2f due to changes in how OpenSSL handles SSL_shutdown() during SSL handshakes. diffstat: src/event/ngx_event_openssl.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diffs (23 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 @@ -1767,6 +1767,19 @@ ngx_ssl_shutdown(ngx_connection_t *c) int n, sslerr, mode; ngx_err_t err; + if (SSL_in_init(c->ssl->connection)) { + /* + * OpenSSL 1.0.2f complains if SSL_shutdown() is called during + * an SSL handshake, while previous versions always return 0. + * Avoid calling SSL_shutdown() if handshake wasn't completed. + */ + + SSL_free(c->ssl->connection); + c->ssl = NULL; + + return NGX_OK; + } + if (c->timedout) { mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; SSL_set_quiet_shutdown(c->ssl->connection, 1); From mdounin at mdounin.ru Fri Feb 19 15:15:02 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 19 Feb 2016 15:15:02 +0000 Subject: [nginx] Configure: added "build" target. Message-ID: details: http://hg.nginx.org/nginx/rev/cfc3cfa434ec branches: changeset: 6408:cfc3cfa434ec user: Maxim Dounin date: Fri Feb 19 18:13:54 2016 +0300 description: Configure: added "build" target. The "build" target introduced to do all build-related tasks, and it is now used in Makefile and in objs/Makefile as a dependency for the "install" target. In particular, this resolves problems as observed with dynamic modules by people trying to do "make install" without calling "make" first. diffstat: auto/install | 5 +---- auto/make | 4 ++++ 2 files changed, 5 insertions(+), 4 deletions(-) diffs (36 lines): diff --git a/auto/install b/auto/install --- a/auto/install +++ b/auto/install @@ -104,8 +104,7 @@ manpage: $NGX_OBJS/nginx.8 -e "s|%%ERROR_LOG_PATH%%|${NGX_ERROR_LOG_PATH:-stderr}|" \\ < $NGX_MAN > \$@ -install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \ - $NGX_INSTALL_PERL_MODULES +install: build $NGX_INSTALL_PERL_MODULES test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX' test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \ @@ -187,8 +186,6 @@ cat << END >> Makefile build: \$(MAKE) -f $NGX_MAKEFILE - \$(MAKE) -f $NGX_MAKEFILE modules - \$(MAKE) -f $NGX_MAKEFILE manpage install: \$(MAKE) -f $NGX_MAKEFILE install diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -223,6 +223,10 @@ ngx_main_link=${MAIN_LINK:+`echo $MAIN_L cat << END >> $NGX_MAKEFILE +build: binary modules manpage + +binary: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} + $NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link $ngx_rcc From nojima at ynojima.com Fri Feb 19 16:21:14 2016 From: nojima at ynojima.com (Yusuke Nojima) Date: Sat, 20 Feb 2016 01:21:14 +0900 Subject: [PATCH] Upstream: Add "before_send" option to the 'proxy_next_upstream'. Message-ID: # HG changeset patch # User Yusuke Nojima # Date 1455896920 0 # Fri Feb 19 15:48:40 2016 +0000 # Node ID 88bbee2e18f6d475ea7ed8ab61b0cb8142c535dc # Parent 5dfc63c1d9ca5ff5a21a2b0238a2b2782549f62c Upstream: Add "before_send" option to the 'proxy_next_upstream'. "error" and "timeout" options are sometimes dangerous because non-idempotent requests (e.g. typical POST requests) are sent to more than one upstream server. When "before_send" option is specified, a request is passed to the next upstream if an error or a timeout has occurred before sending the first byte of the request. With this option, one can avoid the issue mentioned above without losing the ability to deal with the upstream host failures and daemon failures. diff -r 5dfc63c1d9ca -r 88bbee2e18f6 src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Thu Feb 18 15:49:11 2016 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Fri Feb 19 15:48:40 2016 +0000 @@ -220,6 +220,7 @@ { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, + { ngx_string("before_send"), NGX_HTTP_UPSTREAM_FT_BEFORE_SEND }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } }; diff -r 5dfc63c1d9ca -r 88bbee2e18f6 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Thu Feb 18 15:49:11 2016 +0300 +++ b/src/http/ngx_http_upstream.c Fri Feb 19 15:48:40 2016 +0000 @@ -3872,11 +3872,15 @@ } if (status) { + int matches_next_condition = u->conf->next_upstream & ft_type; + if (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_BEFORE_SEND) + matches_next_condition |= !u->request_sent; + u->state->status = status; timeout = u->conf->next_upstream_timeout; if (u->peer.tries == 0 - || !(u->conf->next_upstream & ft_type) + || !matches_next_condition || (u->request_sent && r->request_body_no_buffering) || (timeout && ngx_current_msec - u->peer.start_time >= timeout)) { diff -r 5dfc63c1d9ca -r 88bbee2e18f6 src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Thu Feb 18 15:49:11 2016 +0300 +++ b/src/http/ngx_http_upstream.h Fri Feb 19 15:48:40 2016 +0000 @@ -29,6 +29,7 @@ #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_BEFORE_SEND 0x00002000 #define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000 #define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000 From limit.usus at gmail.com Fri Feb 19 17:44:44 2016 From: limit.usus at gmail.com (Tomoya Kabe) Date: Sat, 20 Feb 2016 02:44:44 +0900 Subject: [PATCH]add proxy_protocol_port variable for rfc6302 In-Reply-To: References: <20151203190316.GG74233@mdounin.ru> <20151207025141.GT74233@mdounin.ru> Message-ID: Hi, Can anybody check this patch? I'm eager to use this feature. 2015-12-08 9:35 GMT+09:00 junpei yoshino : > Hello, > > I made merged patch. > > # HG changeset patch > # User Junpei Yoshino > # Date 1449499172 -32400 > # Mon Dec 07 23:39:32 2015 +0900 > # Node ID f4cd90a03eca5c330f51ac4ba2673e64348c622e > # Parent 29f35e60840b8eed2927dd3495ef2d8e524862f7 > Http: add proxy_protocol_port variable for rfc6302 > > diff -r 29f35e60840b -r f4cd90a03eca src/core/ngx_connection.h > --- a/src/core/ngx_connection.h Mon Dec 07 16:30:48 2015 +0300 > +++ b/src/core/ngx_connection.h Mon Dec 07 23:39:32 2015 +0900 > @@ -146,6 +146,7 @@ > ngx_str_t addr_text; > > ngx_str_t proxy_protocol_addr; > + ngx_int_t proxy_protocol_port; > > #if (NGX_SSL) > ngx_ssl_connection_t *ssl; > diff -r 29f35e60840b -r f4cd90a03eca src/core/ngx_proxy_protocol.c > --- a/src/core/ngx_proxy_protocol.c Mon Dec 07 16:30:48 2015 +0300 > +++ b/src/core/ngx_proxy_protocol.c Mon Dec 07 23:39:32 2015 +0900 > @@ -13,7 +13,7 @@ > ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) > { > size_t len; > - u_char ch, *p, *addr; > + u_char ch, *p, *addr, *port; > > p = buf; > len = last - buf; > @@ -71,8 +71,40 @@ > ngx_memcpy(c->proxy_protocol_addr.data, addr, len); > c->proxy_protocol_addr.len = len; > > - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, > - "PROXY protocol address: \"%V\"", > &c->proxy_protocol_addr); > + for ( ;; ) { > + if (p == last) { > + goto invalid; > + } > + > + ch = *p++; > + > + if (ch == ' ') { > + break; > + } > + } > + port = p; > + for ( ;; ) { > + if (p == last) { > + goto invalid; > + } > + > + ch = *p++; > + > + if (ch == ' ') { > + break; > + } > + > + if (ch < '0' || ch > '9') > + { > + goto invalid; > + } > + } > + len = p - port - 1; > + c->proxy_protocol_port = ngx_atoi(port,len); > + > + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, > + "PROXY protocol address: \"%V\", PROXY protocol > port: \"%d\"", > + &c->proxy_protocol_addr, c->proxy_protocol_port); > > skip: > > diff -r 29f35e60840b -r f4cd90a03eca src/http/ngx_http_variables.c > --- a/src/http/ngx_http_variables.c Mon Dec 07 16:30:48 2015 +0300 > +++ b/src/http/ngx_http_variables.c Mon Dec 07 23:39:32 2015 +0900 > @@ -58,6 +58,8 @@ > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t > *r, > ngx_http_variable_value_t *v, uintptr_t data); > +static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t > *r, > + ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, > @@ -192,6 +194,9 @@ > { ngx_string("proxy_protocol_addr"), NULL, > ngx_http_variable_proxy_protocol_addr, 0, 0, 0 }, > > + { ngx_string("proxy_protocol_port"), NULL, > + ngx_http_variable_proxy_protocol_port, 0, 0, 0 }, > + > { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, > 0, 0, 0 }, > > { ngx_string("server_port"), NULL, ngx_http_variable_server_port, > 0, 0, 0 }, > @@ -1250,6 +1255,29 @@ > > > static ngx_int_t > +ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, > + ngx_http_variable_value_t *v, uintptr_t data) > +{ > + ngx_int_t port = r->connection->proxy_protocol_port; > + > + v->len = 0; > + v->valid = 1; > + v->no_cacheable = 0; > + v->not_found = 0; > + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); > + > + if (v->data == NULL) { > + return NGX_ERROR; > + } > + if (port > 0 && port < 65536) { > + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; > + } > + > + return NGX_OK; > +} > + > + > +static ngx_int_t > ngx_http_variable_server_addr(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data) > { > > > On Tue, Dec 8, 2015 at 12:56 AM, junpei yoshino > wrote: > > Hello. > > > > I wrote additional patch. > > > > # HG changeset patch > > # User Junpei Yoshino > > # Date 1449499172 -32400 > > # Mon Dec 07 23:39:32 2015 +0900 > > # Node ID e2984af905ff8cf523b22860620a9f3ff22d555a > > # Parent 59cadccedf402ec325b078cb72a284465639e0fe > > Change definition of proxy_protocol_port > > > > diff -r 59cadccedf40 -r e2984af905ff src/core/ngx_connection.h > > --- a/src/core/ngx_connection.h Thu Nov 05 20:36:47 2015 +0900 > > +++ b/src/core/ngx_connection.h Mon Dec 07 23:39:32 2015 +0900 > > @@ -146,7 +146,7 @@ > > ngx_str_t addr_text; > > > > ngx_str_t proxy_protocol_addr; > > - ngx_str_t proxy_protocol_port; > > + ngx_int_t proxy_protocol_port; > > > > #if (NGX_SSL) > > ngx_ssl_connection_t *ssl; > > diff -r 59cadccedf40 -r e2984af905ff src/core/ngx_proxy_protocol.c > > --- a/src/core/ngx_proxy_protocol.c Thu Nov 05 20:36:47 2015 +0900 > > +++ b/src/core/ngx_proxy_protocol.c Mon Dec 07 23:39:32 2015 +0900 > > @@ -81,14 +81,6 @@ > > if (ch == ' ') { > > break; > > } > > - > > - if (ch != ':' && ch != '.' > > - && (ch < 'a' || ch > 'f') > > - && (ch < 'A' || ch > 'F') > > - && (ch < '0' || ch > '9')) > > - { > > - goto invalid; > > - } > > } > > port = p; > > for ( ;; ) { > > @@ -108,19 +100,11 @@ > > } > > } > > len = p - port - 1; > > - c->proxy_protocol_port.data = ngx_pnalloc(c->pool, len); > > + c->proxy_protocol_port = ngx_atoi(port,len); > > > > - if (c->proxy_protocol_port.data == NULL) { > > - return NULL; > > - } > > - > > - ngx_memcpy(c->proxy_protocol_port.data, port, len); > > - c->proxy_protocol_port.len = len; > > - > > - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, > > - "PROXY protocol address: \"%V\"", > &c->proxy_protocol_addr); > > - ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, > > - "PROXY protocol port: \"%V\"", > &c->proxy_protocol_port); > > + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, > > + "PROXY protocol address: \"%V\", PROXY protocol > > port: \"%d\"", > > + &c->proxy_protocol_addr, c->proxy_protocol_port); > > > > skip: > > > > diff -r 59cadccedf40 -r e2984af905ff src/http/ngx_http_variables.c > > --- a/src/http/ngx_http_variables.c Thu Nov 05 20:36:47 2015 +0900 > > +++ b/src/http/ngx_http_variables.c Mon Dec 07 23:39:32 2015 +0900 > > @@ -1258,11 +1258,20 @@ > > ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r, > > ngx_http_variable_value_t *v, uintptr_t data) > > { > > - v->len = r->connection->proxy_protocol_port.len; > > + ngx_int_t port = r->connection->proxy_protocol_port; > > + > > + v->len = 0; > > v->valid = 1; > > v->no_cacheable = 0; > > v->not_found = 0; > > - v->data = r->connection->proxy_protocol_port.data; > > + v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); > > + > > + if (v->data == NULL) { > > + return NGX_ERROR; > > + } > > + if (port > 0 && port < 65536) { > > + v->len = ngx_sprintf(v->data, "%ui", port) - v->data; > > + } > > > > return NGX_OK; > > } > > > > > > On Mon, Dec 7, 2015 at 11:51 AM, Maxim Dounin > wrote: > >> Hello! > >> > >> On Mon, Dec 07, 2015 at 12:14:38AM +0900, junpei yoshino wrote: > >> > >>> > but we need someone to do the rest of the work. > >>> > >>> Could I contribute it? > >>> At first, I will revise this patch along your review. > >> > >> It may be a bit too many for someone with small nginx coding > >> experience, but you may try to. > >> > >> -- > >> Maxim Dounin > >> http://nginx.org/ > >> > >> _______________________________________________ > >> nginx-devel mailing list > >> nginx-devel at nginx.org > >> http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > > > > > -- > > junpei.yoshino at gmail.com > > > > -- > junpei.yoshino at gmail.com > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Tomoya KABE Mail : limit.usus at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From piotrsikora at google.com Sat Feb 20 00:09:23 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Fri, 19 Feb 2016 16:09:23 -0800 Subject: [nginx] Configure: skip building OpenSSL documentation to conserve time. In-Reply-To: References: Message-ID: Hello, > Configure: skip building OpenSSL documentation to conserve time. > > The install_sw target first appeared in OpenSSL 0.9.7e and is documented since > OpenSSL 1.0.0 as the way to install the OpenSSL software without documentation. What's the oldest OpenSSL version supported by nginx now? Last time I tried to push this exact change [1][2], Maxim told me that it's not going to be accepted because nginx supports OpenSSL-0.9.7 [3]. [1] http://mailman.nginx.org/pipermail/nginx-devel/2013-November/004489.html [2] http://mailman.nginx.org/pipermail/nginx-devel/2013-November/004497.html [3] http://mailman.nginx.org/pipermail/nginx-devel/2013-November/004492.html Best regards, Piotr Sikora From jonathan at autoit4you.de Sun Feb 21 10:58:55 2016 From: jonathan at autoit4you.de (Jonathan Horn) Date: Sun, 21 Feb 2016 11:58:55 +0100 Subject: Status of dual certificate support Message-ID: <56C9986F.5060207@autoit4you.de> Hi all, I wanted to know what the current status is to get dual certificate support into nginx. I saw that there have been some patches in March and April last year, but with no indication why the final version in April hasn't been merged. Is there any work currently done on bringing this into nginx? Or is some other feature development currently blocking this? Is there something else that I can help with to get that support into nginx? Jonathan Horn From mdounin at mdounin.ru Sun Feb 21 13:16:17 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sun, 21 Feb 2016 16:16:17 +0300 Subject: [nginx] Configure: skip building OpenSSL documentation to conserve time. In-Reply-To: References: Message-ID: <20160221131616.GA31796@mdounin.ru> Hello! On Fri, Feb 19, 2016 at 04:09:23PM -0800, Piotr Sikora wrote: > Hello, > > > Configure: skip building OpenSSL documentation to conserve time. > > > > The install_sw target first appeared in OpenSSL 0.9.7e and is documented since > > OpenSSL 1.0.0 as the way to install the OpenSSL software without documentation. > > What's the oldest OpenSSL version supported by nginx now? > > Last time I tried to push this exact change [1][2], Maxim told me that > it's not going to be accepted because nginx supports OpenSSL-0.9.7 > [3]. And the same change was previously rejected as well, with the same reasoning: http://mailman.nginx.org/pipermail/nginx/2012-August/034889.html Now we are moving away from OpenSSL 0.9.7 support, targeting OpenSSL 0.9.8 as a minimum supported version. This patch effectively limits minimum OpenSSL version nginx is able to build to OpenSSL 0.9.7e, though older versions are still supported in the code. Support for older versions is likely to be removed from the code in the upcoming nginx versions. -- Maxim Dounin http://nginx.org/ From toshic.toshic at gmail.com Sun Feb 21 19:07:41 2016 From: toshic.toshic at gmail.com (ToSHiC) Date: Sun, 21 Feb 2016 22:07:41 +0300 Subject: Status of dual certificate support In-Reply-To: <56C9986F.5060207@autoit4you.de> References: <56C9986F.5060207@autoit4you.de> Message-ID: Hello, We are using patches from here: https://github.com/wikimedia/operations-software-nginx/tree/wmf-1.9.2-1/debian/patches in production since 20th of December 2015. We've made 2 certificates: EC+SHA2 signature for new browsers and RSA+SHA1 signature for old ones. We assume that all browsers that supports EC certs does support SHA2 certs signature. Monitoring of bad SSL connections from nginx' error.log shows no additional errors so we think our assumption is correct. Certificate election mechanism is based on cipher suites from ClientHello and unfortunately there is no certificate signature type in cypher suite string. If you'll try to make the same configuration you need to force server cipher suites over clients, and carefully place ECDSA before RSA. To check if everything works fine use openssl s_client utility with -cipher options. RSA should be enabled only if ECDSA is not present in client ciphers. To monitor proper certificate usage in production we use ssl_cipher variable. Additioanlly we've added variable with currently used server certificate serial number, just to be sure. Our logs shows that in December ~20-25% of clients have used RSA certificate in our configuration. Please feel free to contact me if you have any questions. Regards, Anton Kortunov. On Sun, Feb 21, 2016 at 1:58 PM, Jonathan Horn wrote: > Hi all, > > I wanted to know what the current status is to get dual certificate > support into nginx. > > I saw that there have been some patches in March and April last year, > but with no indication why the final version in April hasn't been merged. > > Is there any work currently done on bringing this into nginx? Or is some > other feature development currently blocking this? Is there something > else that I can help with to get that support into nginx? > > Jonathan Horn > > _______________________________________________ > 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 albertcasademont at gmail.com Sun Feb 21 21:08:35 2016 From: albertcasademont at gmail.com (Albert Casademont) Date: Sun, 21 Feb 2016 23:08:35 +0200 Subject: Status of dual certificate support In-Reply-To: References: <56C9986F.5060207@autoit4you.de> Message-ID: It would be great if these patches were merged upstream! On Sunday, 21 February 2016, ToSHiC wrote: > Hello, > > We are using patches from here: > https://github.com/wikimedia/operations-software-nginx/tree/wmf-1.9.2-1/debian/patches > in production since 20th of December 2015. > > We've made 2 certificates: EC+SHA2 signature for new browsers and RSA+SHA1 > signature for old ones. We assume that all browsers that supports EC certs > does support SHA2 certs signature. Monitoring of bad SSL connections from > nginx' error.log shows no additional errors so we think our assumption is > correct. Certificate election mechanism is based on cipher suites from > ClientHello and unfortunately there is no certificate signature type in > cypher suite string. > > If you'll try to make the same configuration you need to force server > cipher suites over clients, and carefully place ECDSA before RSA. To check > if everything works fine use openssl s_client utility with -cipher options. > RSA should be enabled only if ECDSA is not present in client ciphers. > > To monitor proper certificate usage in production we use ssl_cipher > variable. Additioanlly we've added variable with currently used server > certificate serial number, just to be sure. Our logs shows that in December > ~20-25% of clients have used RSA certificate in our configuration. > > Please feel free to contact me if you have any questions. > > Regards, > Anton Kortunov. > > On Sun, Feb 21, 2016 at 1:58 PM, Jonathan Horn > wrote: > >> Hi all, >> >> I wanted to know what the current status is to get dual certificate >> support into nginx. >> >> I saw that there have been some patches in March and April last year, >> but with no indication why the final version in April hasn't been merged. >> >> Is there any work currently done on bringing this into nginx? Or is some >> other feature development currently blocking this? Is there something >> else that I can help with to get that support into nginx? >> >> Jonathan Horn >> >> _______________________________________________ >> 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 Feb 22 06:26:02 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Sun, 21 Feb 2016 22:26:02 -0800 Subject: [PATCH] Style: add missing braces Message-ID: <1c8c7348262e5c00fa4d.1456122362@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1456122109 28800 # Sun Feb 21 22:21:49 2016 -0800 # Node ID 1c8c7348262e5c00fa4d64333d4de2fe92961934 # Parent cfc3cfa434ec1e53989f8499e42bf448b9747ec9 Style: add missing braces. Signed-off-by: Piotr Sikora diff -r cfc3cfa434ec -r 1c8c7348262e src/core/ngx_parse_time.c --- a/src/core/ngx_parse_time.c +++ b/src/core/ngx_parse_time.c @@ -44,14 +44,15 @@ ngx_parse_http_time(u_char *value, size_ } } - for (p++; p < end; p++) + for (p++; p < end; p++) { if (*p != ' ') { break; } + } if (end - p < 18) { return NGX_ERROR; - } + } if (fmt != isoc) { if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { diff -r cfc3cfa434ec -r 1c8c7348262e 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 @@ -359,11 +359,13 @@ ngx_http_header_filter(ngx_http_request_ if (clcf->port_in_redirect) { #if (NGX_HTTP_SSL) - if (c->ssl) + if (c->ssl) { port = (port == 443) ? 0 : port; - else + } else #endif + { port = (port == 80) ? 0 : port; + } } else { port = 0; diff -r cfc3cfa434ec -r 1c8c7348262e 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 @@ -305,11 +305,13 @@ ngx_http_v2_header_filter(ngx_http_reque if (clcf->port_in_redirect) { #if (NGX_HTTP_SSL) - if (fc->ssl) + if (fc->ssl) { port = (port == 443) ? 0 : port; - else + } else #endif + { port = (port == 80) ? 0 : port; + } } else { port = 0; From piotrsikora at google.com Mon Feb 22 06:26:28 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Sun, 21 Feb 2016 22:26:28 -0800 Subject: [PATCH] Style: add missing includes and include guards Message-ID: <863f4a52ae07be12dfb9.1456122388@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1456122112 28800 # Sun Feb 21 22:21:52 2016 -0800 # Node ID 863f4a52ae07be12dfb9f57ba4280d490554e59d # Parent cfc3cfa434ec1e53989f8499e42bf448b9747ec9 Style: add missing includes and include guards. Signed-off-by: Piotr Sikora diff -r cfc3cfa434ec -r 863f4a52ae07 src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,6 +9,10 @@ #define _NGINX_H_INCLUDED_ +#include +#include + + #define nginx_version 1009012 #define NGINX_VERSION "1.9.12" #define NGINX_VER "nginx/" NGINX_VERSION diff -r cfc3cfa434ec -r 863f4a52ae07 src/core/ngx_syslog.h --- a/src/core/ngx_syslog.h +++ b/src/core/ngx_syslog.h @@ -8,6 +8,10 @@ #define _NGX_SYSLOG_H_INCLUDED_ +#include +#include + + typedef struct { ngx_pool_t *pool; ngx_uint_t facility; diff -r cfc3cfa434ec -r 863f4a52ae07 src/event/modules/ngx_iocp_module.h --- a/src/event/modules/ngx_iocp_module.h +++ b/src/event/modules/ngx_iocp_module.h @@ -9,6 +9,10 @@ #define _NGX_IOCP_MODULE_H_INCLUDED_ +#include +#include + + typedef struct { int threads; int post_acceptex; diff -r cfc3cfa434ec -r 863f4a52ae07 src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -9,6 +9,11 @@ #define _NGX_HTTP_REQUEST_H_INCLUDED_ +#include +#include +#include + + #define NGX_HTTP_MAX_URI_CHANGES 10 #define NGX_HTTP_MAX_SUBREQUESTS 50 diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_darwin.h --- a/src/os/unix/ngx_darwin.h +++ b/src/os/unix/ngx_darwin.h @@ -9,6 +9,10 @@ #define _NGX_DARWIN_H_INCLUDED_ +#include +#include + + void ngx_debug_init(void); ngx_chain_t *ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_freebsd.h --- a/src/os/unix/ngx_freebsd.h +++ b/src/os/unix/ngx_freebsd.h @@ -9,6 +9,10 @@ #define _NGX_FREEBSD_H_INCLUDED_ +#include +#include + + void ngx_debug_init(void); ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_gcc_atomic_amd64.h --- a/src/os/unix/ngx_gcc_atomic_amd64.h +++ b/src/os/unix/ngx_gcc_atomic_amd64.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_GCC_ATOMIC_AMD64_H_INCLUDED_ +#define _NGX_GCC_ATOMIC_AMD64_H_INCLUDED_ + + +#include +#include + + #if (NGX_SMP) #define NGX_SMP_LOCK "lock;" #else @@ -80,3 +88,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory") #define ngx_cpu_pause() __asm__ ("pause") + + +#endif /* _NGX_GCC_ATOMIC_AMD64_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_gcc_atomic_ppc.h --- a/src/os/unix/ngx_gcc_atomic_ppc.h +++ b/src/os/unix/ngx_gcc_atomic_ppc.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_GCC_ATOMIC_PPC_H_INCLUDED_ +#define _NGX_GCC_ATOMIC_PPC_H_INCLUDED_ + + +#include +#include + + /* * The ppc assembler treats ";" as comment, so we have to use "\n". * The minus in "bne-" is a hint for the branch prediction unit that @@ -153,3 +161,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #define ngx_cpu_pause() + + +#endif /* _NGX_GCC_ATOMIC_PPC_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_gcc_atomic_sparc64.h --- a/src/os/unix/ngx_gcc_atomic_sparc64.h +++ b/src/os/unix/ngx_gcc_atomic_sparc64.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_GCC_ATOMIC_SPARC64_H_INCLUDED_ +#define _NGX_GCC_ATOMIC_SPARC64_H_INCLUDED_ + + +#include +#include + + /* * "casa [r1] 0x80, r2, r0" and * "casxa [r1] 0x80, r2, r0" do the following: @@ -80,3 +88,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #endif #define ngx_cpu_pause() + + +#endif /* _NGX_GCC_ATOMIC_SPARC64_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_gcc_atomic_x86.h --- a/src/os/unix/ngx_gcc_atomic_x86.h +++ b/src/os/unix/ngx_gcc_atomic_x86.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_GCC_ATOMIC_X86_H_INCLUDED_ +#define _NGX_GCC_ATOMIC_X86_H_INCLUDED_ + + +#include +#include + + #if (NGX_SMP) #define NGX_SMP_LOCK "lock;" #else @@ -125,3 +133,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value /* old "as" does not support "pause" opcode */ #define ngx_cpu_pause() __asm__ (".byte 0xf3, 0x90") + + +#endif /* _NGX_GCC_ATOMIC_X86_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_linux.h --- a/src/os/unix/ngx_linux.h +++ b/src/os/unix/ngx_linux.h @@ -9,6 +9,10 @@ #define _NGX_LINUX_H_INCLUDED_ +#include +#include + + ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_process.h --- a/src/os/unix/ngx_process.h +++ b/src/os/unix/ngx_process.h @@ -9,6 +9,8 @@ #define _NGX_PROCESS_H_INCLUDED_ +#include +#include #include #include diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_setaffinity.h --- a/src/os/unix/ngx_setaffinity.h +++ b/src/os/unix/ngx_setaffinity.h @@ -7,6 +7,10 @@ #define _NGX_SETAFFINITY_H_INCLUDED_ +#include +#include + + #if (NGX_HAVE_SCHED_SETAFFINITY || NGX_HAVE_CPUSET_SETAFFINITY) #define NGX_HAVE_CPU_AFFINITY 1 diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_setproctitle.h --- a/src/os/unix/ngx_setproctitle.h +++ b/src/os/unix/ngx_setproctitle.h @@ -9,6 +9,10 @@ #define _NGX_SETPROCTITLE_H_INCLUDED_ +#include +#include + + #if (NGX_HAVE_SETPROCTITLE) /* FreeBSD, NetBSD, OpenBSD */ diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_socket.h --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -10,6 +10,7 @@ #include +#include #define NGX_WRITE_SHUTDOWN SHUT_WR diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_solaris.h --- a/src/os/unix/ngx_solaris.h +++ b/src/os/unix/ngx_solaris.h @@ -9,6 +9,10 @@ #define _NGX_SOLARIS_H_INCLUDED_ +#include +#include + + ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/unix/ngx_sunpro_atomic_sparc64.h --- a/src/os/unix/ngx_sunpro_atomic_sparc64.h +++ b/src/os/unix/ngx_sunpro_atomic_sparc64.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_SUNPRO_ATOMIC_SPARC64_H_INCLUDED_ +#define _NGX_SUNPRO_ATOMIC_SPARC64_H_INCLUDED_ + + +#include +#include + + #if (NGX_PTR_SIZE == 4) #define NGX_CASA ngx_casa #else @@ -59,3 +67,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value __asm (".nonvolatile") #define ngx_cpu_pause() + + +#endif /* _NGX_SUNPRO_ATOMIC_SPARC64_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/win32/ngx_process.h --- a/src/os/win32/ngx_process.h +++ b/src/os/win32/ngx_process.h @@ -9,6 +9,10 @@ #define _NGX_PROCESS_H_INCLUDED_ +#include +#include + + typedef DWORD ngx_pid_t; #define NGX_INVALID_PID 0 diff -r cfc3cfa434ec -r 863f4a52ae07 src/os/win32/ngx_service.c --- a/src/os/win32/ngx_service.c +++ b/src/os/win32/ngx_service.c @@ -5,6 +5,9 @@ */ +#include +#include + #define NGX_SERVICE_CONTROL_SHUTDOWN 128 #define NGX_SERVICE_CONTROL_REOPEN 129 From auskov at neolabs.kz Mon Feb 22 06:22:57 2016 From: auskov at neolabs.kz (Alexander Uskov) Date: Mon, 22 Feb 2016 12:22:57 +0600 (ALMT) Subject: =?UTF-8?B?U0lHQUJSVCDQsiDRgdCw0LzQvtC/0LjRgdC90L7QvCDQvNC+0LTRg9C70LU=?= In-Reply-To: <31370628.5888.1456125660261.JavaMail.al@nlb01lx002> Message-ID: <13994212.5891.1456126206997.JavaMail.al@nlb01lx002> ????? ????. ???? ?????????? ?????? ?? ????????? ???????: ??????? ????????? ? url, ???? ???? ???????????? GET ????????, ?? ?????? ???? ? ?????, ??????? ? ??? %V ?? ???????? ?????????, ???? ???, ?? ?????????? ???????? ???????? ????, ???? ??? ? ???, ?? ????????? ???? ???????? ? ??????? ?????????? ???????? ?? ?????????=????????. ?????? ????? ???? 2 ?????, ??? ? C ?????? ??????. ???????????? ??????? ?????? ???????? ? ??????????. ????????? ??????????? ??? ?? ????? ?????? (?????????? ????, ??? ?????? ???????? ???? ?????-?? ??????????), ????????? ?????????: *** Error in `nginx: worker process': double free or corruption (!prev): 0x0000000001ad6180 *** ======= Backtrace: ========= /lib64/libc.so.6(+0x7d023)[0x7f19765a8023] nginx: worker process(ngx_destroy_pool+0x6f)[0x412a7f] nginx: worker process(ngx_http_free_request+0x108)[0x444438] nginx: worker process[0x444c49] nginx: worker process(ngx_http_core_content_phase+0x39)[0x440a29] nginx: worker process(ngx_http_core_run_phases+0x25)[0x43b2d5] nginx: worker process(ngx_http_process_request+0xa3)[0x446113] nginx: worker process[0x446976] nginx: worker process[0x431dd7] nginx: worker process(ngx_process_events_and_timers+0x53)[0x42a293] nginx: worker process[0x42fe41] nginx: worker process(ngx_spawn_process+0x164)[0x42e854] nginx: worker process[0x430014] nginx: worker process(ngx_master_process_cycle+0x1cb)[0x430adb] nginx: worker process(main+0x826)[0x4106d6] /lib64/libc.so.6(__libc_start_main+0xf5)[0x7f197654cb15] nginx: worker process[0x4109f1] ======= Memory map: ======== 00400000-004b7000 r-xp 00000000 08:03 8257917 /usr/sbin/nginx 006b6000-006b7000 r--p 000b6000 08:03 8257917 /usr/sbin/nginx 006b7000-006ce000 rw-p 000b7000 08:03 8257917 /usr/sbin/nginx 006ce000-006dd000 rw-p 00000000 00:00 0 01aa5000-01b8d000 rw-p 00000000 00:00 0 [heap] 01b8d000-01bcf000 rw-p 00000000 00:00 0 [heap] 7f196c000000-7f196c021000 rw-p 00000000 00:00 0 7f196c021000-7f1970000000 ---p 00000000 00:00 0 7f19723db000-7f19723f0000 r-xp 00000000 08:03 2097154 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 ... 7f1977e61000-7f1977e62000 rw-p 00000000 00:00 0 7ffcbba5a000-7ffcbba7b000 rw-p 00000000 00:00 0 [stack] 7ffcbbb24000-7ffcbbb26000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] 2016/02/22 12:34:43 [alert] 22924#0: worker process 22925 exited on signal 6 *** Error in `nginx: worker process': double free or corruption (!prev): 0x0000000001b40cf0 *** ??????? ?? ?? ??? ???????, ? ?????? ??? ????????? :( ??????? ??????????????? ?????? ??????. ????????? ???? ?????????????????, ???????? ?????????? ?????? ? ?????, ????? ???? ?????? ??? ?????????. ?-? ???????? ???-?? ? ????????? ??????? ????: // ????????, ???????? ?? ??? ? GET, ???????? ?? GET['c'] ? ??? ??????, ???? ??, ?? ???? ?? ?????, ????? - ????????. if (r->args.len && ngx_http_arg(r, (u_char *) zero_js_config->get_parm.data, zero_js_config->get_parm.len, &get_c) == NGX_OK && get_c.len <=14 && get_c.len>10) { /* void() */ } else { // ?????? ???????? ? ????? ? GET // ???????? ????? COOKIE['client_cc'] n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &zero_js_config->cookie_name, &cookie); // ???? ???? ???? ? ?? ?????? <=14 ??????? ???????? ? uniqid ????? ??????? php_uniqid() if (n != NGX_DECLINED && cookie.len<=14) { ngx_sprintf(uniqid, "%V", &cookie); } else { ngx_gettimeofday(&tv); sec = (int) tv.tv_sec; usec = (int) (tv.tv_usec % 0x100000); ngx_sprintf(uniqid, "%i%08xi%05xi", ngx_random() % 10, sec, usec); } // ??????? url ??? ????????? turl = ngx_pcalloc(r->pool, sizeof("?=") - 1 + zero_js_config->get_parm.len + sizeof(uniqid)); if (turl == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_sprintf(turl, "?%V=%s", &zero_js_config->get_parm, uniqid); // ????????? Location r->headers_out.location = ngx_list_push(&r->headers_out.headers); if (r->headers_out.location == NULL) { return NGX_ERROR; } r->headers_out.location->hash = 1; r->headers_out.location->key.len = sizeof("Location") - 1; r->headers_out.location->key.data = (u_char *) "Location"; r->headers_out.location->value.len = sizeof("?=") - 1 + zero_js_config->get_parm.len + sizeof(uniqid); r->headers_out.location->value.data = turl; return NGX_HTTP_MOVED_PERMANENTLY; // ?????? ???????? } ??? ??? ????? ???? ?? ???, ??? nginx ?????? ? double free or corruption? ??? ???????????, ??? ??? ????? ????????? ????? ???????? (ab ??? curl ???????????) ????????? ???????? ?? ????. ??????? - ??????? 8k ???????? ? ??????? - ??????? ???????? :D ~~~ wbr, Alexander Uskov From piotrsikora at google.com Mon Feb 22 22:05:47 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 22 Feb 2016 14:05:47 -0800 Subject: [PATCH] Style: add missing includes and include guards In-Reply-To: <863f4a52ae07be12dfb9.1456122388@piotrsikora.sfo.corp.google.com> References: <863f4a52ae07be12dfb9.1456122388@piotrsikora.sfo.corp.google.com> Message-ID: <912aa4fe688b98393a14.1456178747@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1456178502 28800 # Mon Feb 22 14:01:42 2016 -0800 # Node ID 912aa4fe688b98393a145acd2f590bd54ad70c6a # Parent cfc3cfa434ec1e53989f8499e42bf448b9747ec9 Style: add missing includes and include guards. Signed-off-by: Piotr Sikora diff -r cfc3cfa434ec -r 912aa4fe688b src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,6 +9,9 @@ #define _NGINX_H_INCLUDED_ +#include + + #define nginx_version 1009012 #define NGINX_VERSION "1.9.12" #define NGINX_VER "nginx/" NGINX_VERSION diff -r cfc3cfa434ec -r 912aa4fe688b src/core/ngx_syslog.h --- a/src/core/ngx_syslog.h +++ b/src/core/ngx_syslog.h @@ -8,6 +8,10 @@ #define _NGX_SYSLOG_H_INCLUDED_ +#include +#include + + typedef struct { ngx_pool_t *pool; ngx_uint_t facility; diff -r cfc3cfa434ec -r 912aa4fe688b src/event/modules/ngx_iocp_module.h --- a/src/event/modules/ngx_iocp_module.h +++ b/src/event/modules/ngx_iocp_module.h @@ -9,6 +9,10 @@ #define _NGX_IOCP_MODULE_H_INCLUDED_ +#include +#include + + typedef struct { int threads; int post_acceptex; diff -r cfc3cfa434ec -r 912aa4fe688b src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -9,6 +9,11 @@ #define _NGX_HTTP_REQUEST_H_INCLUDED_ +#include +#include +#include + + #define NGX_HTTP_MAX_URI_CHANGES 10 #define NGX_HTTP_MAX_SUBREQUESTS 50 diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_darwin.h --- a/src/os/unix/ngx_darwin.h +++ b/src/os/unix/ngx_darwin.h @@ -9,6 +9,10 @@ #define _NGX_DARWIN_H_INCLUDED_ +#include +#include + + void ngx_debug_init(void); ngx_chain_t *ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_freebsd.h --- a/src/os/unix/ngx_freebsd.h +++ b/src/os/unix/ngx_freebsd.h @@ -9,6 +9,10 @@ #define _NGX_FREEBSD_H_INCLUDED_ +#include +#include + + void ngx_debug_init(void); ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_gcc_atomic_amd64.h --- a/src/os/unix/ngx_gcc_atomic_amd64.h +++ b/src/os/unix/ngx_gcc_atomic_amd64.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_GCC_ATOMIC_AMD64_H_INCLUDED_ +#define _NGX_GCC_ATOMIC_AMD64_H_INCLUDED_ + + +#include +#include + + #if (NGX_SMP) #define NGX_SMP_LOCK "lock;" #else @@ -80,3 +88,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #define ngx_memory_barrier() __asm__ volatile ("" ::: "memory") #define ngx_cpu_pause() __asm__ ("pause") + + +#endif /* _NGX_GCC_ATOMIC_AMD64_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_gcc_atomic_ppc.h --- a/src/os/unix/ngx_gcc_atomic_ppc.h +++ b/src/os/unix/ngx_gcc_atomic_ppc.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_GCC_ATOMIC_PPC_H_INCLUDED_ +#define _NGX_GCC_ATOMIC_PPC_H_INCLUDED_ + + +#include +#include + + /* * The ppc assembler treats ";" as comment, so we have to use "\n". * The minus in "bne-" is a hint for the branch prediction unit that @@ -153,3 +161,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #define ngx_cpu_pause() + + +#endif /* _NGX_GCC_ATOMIC_PPC_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_gcc_atomic_sparc64.h --- a/src/os/unix/ngx_gcc_atomic_sparc64.h +++ b/src/os/unix/ngx_gcc_atomic_sparc64.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_GCC_ATOMIC_SPARC64_H_INCLUDED_ +#define _NGX_GCC_ATOMIC_SPARC64_H_INCLUDED_ + + +#include +#include + + /* * "casa [r1] 0x80, r2, r0" and * "casxa [r1] 0x80, r2, r0" do the following: @@ -80,3 +88,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value #endif #define ngx_cpu_pause() + + +#endif /* _NGX_GCC_ATOMIC_SPARC64_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_gcc_atomic_x86.h --- a/src/os/unix/ngx_gcc_atomic_x86.h +++ b/src/os/unix/ngx_gcc_atomic_x86.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_GCC_ATOMIC_X86_H_INCLUDED_ +#define _NGX_GCC_ATOMIC_X86_H_INCLUDED_ + + +#include +#include + + #if (NGX_SMP) #define NGX_SMP_LOCK "lock;" #else @@ -125,3 +133,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value /* old "as" does not support "pause" opcode */ #define ngx_cpu_pause() __asm__ (".byte 0xf3, 0x90") + + +#endif /* _NGX_GCC_ATOMIC_X86_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_linux.h --- a/src/os/unix/ngx_linux.h +++ b/src/os/unix/ngx_linux.h @@ -9,6 +9,10 @@ #define _NGX_LINUX_H_INCLUDED_ +#include +#include + + ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_process.h --- a/src/os/unix/ngx_process.h +++ b/src/os/unix/ngx_process.h @@ -9,6 +9,8 @@ #define _NGX_PROCESS_H_INCLUDED_ +#include +#include #include #include diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_setaffinity.h --- a/src/os/unix/ngx_setaffinity.h +++ b/src/os/unix/ngx_setaffinity.h @@ -7,6 +7,10 @@ #define _NGX_SETAFFINITY_H_INCLUDED_ +#include +#include + + #if (NGX_HAVE_SCHED_SETAFFINITY || NGX_HAVE_CPUSET_SETAFFINITY) #define NGX_HAVE_CPU_AFFINITY 1 diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_setproctitle.h --- a/src/os/unix/ngx_setproctitle.h +++ b/src/os/unix/ngx_setproctitle.h @@ -9,6 +9,10 @@ #define _NGX_SETPROCTITLE_H_INCLUDED_ +#include +#include + + #if (NGX_HAVE_SETPROCTITLE) /* FreeBSD, NetBSD, OpenBSD */ diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_socket.h --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -10,6 +10,7 @@ #include +#include #define NGX_WRITE_SHUTDOWN SHUT_WR diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_solaris.h --- a/src/os/unix/ngx_solaris.h +++ b/src/os/unix/ngx_solaris.h @@ -9,6 +9,10 @@ #define _NGX_SOLARIS_H_INCLUDED_ +#include +#include + + ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff -r cfc3cfa434ec -r 912aa4fe688b src/os/unix/ngx_sunpro_atomic_sparc64.h --- a/src/os/unix/ngx_sunpro_atomic_sparc64.h +++ b/src/os/unix/ngx_sunpro_atomic_sparc64.h @@ -5,6 +5,14 @@ */ +#ifndef _NGX_SUNPRO_ATOMIC_SPARC64_H_INCLUDED_ +#define _NGX_SUNPRO_ATOMIC_SPARC64_H_INCLUDED_ + + +#include +#include + + #if (NGX_PTR_SIZE == 4) #define NGX_CASA ngx_casa #else @@ -59,3 +67,6 @@ ngx_atomic_fetch_add(ngx_atomic_t *value __asm (".nonvolatile") #define ngx_cpu_pause() + + +#endif /* _NGX_SUNPRO_ATOMIC_SPARC64_H_INCLUDED_ */ diff -r cfc3cfa434ec -r 912aa4fe688b src/os/win32/ngx_process.h --- a/src/os/win32/ngx_process.h +++ b/src/os/win32/ngx_process.h @@ -9,6 +9,10 @@ #define _NGX_PROCESS_H_INCLUDED_ +#include +#include + + typedef DWORD ngx_pid_t; #define NGX_INVALID_PID 0 diff -r cfc3cfa434ec -r 912aa4fe688b src/os/win32/ngx_service.c --- a/src/os/win32/ngx_service.c +++ b/src/os/win32/ngx_service.c @@ -5,6 +5,9 @@ */ +#include +#include + #define NGX_SERVICE_CONTROL_SHUTDOWN 128 #define NGX_SERVICE_CONTROL_REOPEN 129 From piotrsikora at google.com Mon Feb 22 22:07:10 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 22 Feb 2016 14:07:10 -0800 Subject: [PATCH] Style: add missing includes and include guards In-Reply-To: <863f4a52ae07be12dfb9.1456122388@piotrsikora.sfo.corp.google.com> References: <863f4a52ae07be12dfb9.1456122388@piotrsikora.sfo.corp.google.com> Message-ID: Hey, > diff -r cfc3cfa434ec -r 863f4a52ae07 src/core/nginx.h > --- a/src/core/nginx.h > +++ b/src/core/nginx.h > @@ -9,6 +9,10 @@ > #define _NGINX_H_INCLUDED_ > > > +#include > +#include > + > + > #define nginx_version 1009012 > #define NGINX_VERSION "1.9.12" > #define NGINX_VER "nginx/" NGINX_VERSION nginx.h doesn't need to include , updated patch sent. Best regards, Piotr Sikora From tolga.ceylan at gmail.com Mon Feb 22 23:28:40 2016 From: tolga.ceylan at gmail.com (Tolga Ceylan) Date: Mon, 22 Feb 2016 15:28:40 -0800 Subject: [PATCH] Upstream: Add "before_send" option to the 'proxy_next_upstream'. In-Reply-To: References: Message-ID: On Fri, Feb 19, 2016 at 8:21 AM, Yusuke Nojima wrote: > diff -r 5dfc63c1d9ca -r 88bbee2e18f6 src/http/ngx_http_upstream.c > --- a/src/http/ngx_http_upstream.c Thu Feb 18 15:49:11 2016 +0300 > +++ b/src/http/ngx_http_upstream.c Fri Feb 19 15:48:40 2016 +0000 > @@ -3872,11 +3872,15 @@ > } > > if (status) { > + int matches_next_condition = u->conf->next_upstream & ft_type; > + if (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_BEFORE_SEND) > + matches_next_condition |= !u->request_sent; > + > u->state->status = status; > timeout = u->conf->next_upstream_timeout; > > if (u->peer.tries == 0 > - || !(u->conf->next_upstream & ft_type) > + || !matches_next_condition > || (u->request_sent && r->request_body_no_buffering) > || (timeout && ngx_current_msec - u->peer.start_time >= timeout)) > { Hi All, The patch seems to address an important issue, however one of the conditions in the above if statement is: > || (u->request_sent && r->request_body_no_buffering) which should guarantee that the request can be sent again *only* if it's not already sent. I easily understand "request_sent" flag here, but inclusion of "request_body_no_buffering" flag seems wrong. "request_body_no_buffering" seems to be flag to manage early/buffered reads and I can't determine why it's relevant at all here. In other words, instead of this patch, shouldn't we modify that line as below? > || u->request_sent Regards, Tolga Ceylan From mberkvens at synedge.com Tue Feb 23 08:43:00 2016 From: mberkvens at synedge.com (Martijn Berkvens) Date: Tue, 23 Feb 2016 08:43:00 +0000 Subject: Slice module In-Reply-To: <20160218171418.GB13730@Romans-MacBook-Air.local> References: <16B0B0D7-0DD0-4F04-A837-503BCABC629E@synedge.com> <20160218171418.GB13730@Romans-MacBook-Air.local> Message-ID: <088C1C3B-314D-4D91-B802-F1E1CF042FED@synedge.com> Hi Roman, > On 18 Feb 2016, at 18:14, Roman Arutyunyan wrote: > > Hi Martijn, > > On Wed, Feb 17, 2016 at 09:20:37AM +0000, Martijn Berkvens wrote: >> Hi, >> >> First off, thank you for the work on the slice module. We?re currently using a lua implementation to achieve something similar but this has its shortcomings and we would prefer to use this module. >> >> We?ve been testing this module and when using range requests it works as expected, but when doing normal requests (without a request range) the module still slices the content when the configured slice size is met resulting in corrupt data as it will only serve out the configured slice size and not the entire requested file. > > Module slices all requests, whether they have Range header or not. > This lets nginx reuse already cached slices. This explains the behaviour I?m seeing then and there actually is no issue, it was my miss interpretation of how to implement it. I was doing something like this: set $cachekey "$scheme$http_host$uri$is_args$args?; if ($http_range) { set $cachekey ?$cachekey $slice_range?; } slice 1m; proxy_cache_key $cachekey; After removing the unneeded if clause and just adding $slice_range to the cachekey for all requests everything worked as expected. Great to see that nginx reuses all slices to assemble a full file if requested. Thanks again for your work and apologies for the confusion. Martijn > > Please describe in detail what exactly is corrupted and show your > configuration. Nothing should be corrupted when using the slice module, the > entire file should be assembled of slices and sent to client once you > configured nginx correctly. > >> We run into these issues because a server or location configuration within nginx would service both normal requests as range requests and we have files exceeding the slice size in both cases. >> >> Ideally the slice module would only do its magic when a request contains $http_range. We?ve tried creating a map which would set the slice size to 0 (to disable slicing) when no $http_range is present, but unfortunately the slice directive currently does not support variables. >> >> For our use case it would most likely be sufficient to add variable support to the slice directive. It is understood and acceptable that we would have duplicate cached content in cases where we have both the sliced versions of the file as the entire file. > > You can have that by adding another location for files cached as a whole > and rewriting your request to that location when $http_range is empty. > > -- > Roman Arutyunyan > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From vbart at nginx.com Wed Feb 24 13:05:37 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 24 Feb 2016 13:05:37 +0000 Subject: [nginx] Fixed buffer over-read while logging invalid request headers. Message-ID: details: http://hg.nginx.org/nginx/rev/71edd9192f24 branches: changeset: 6409:71edd9192f24 user: Valentin Bartenev date: Wed Feb 24 16:01:23 2016 +0300 description: Fixed buffer over-read while logging invalid request headers. Since 667aaf61a778 (1.1.17) the ngx_http_parse_header_line() function can return NGX_HTTP_PARSE_INVALID_HEADER when a header contains NUL character. In this case the r->header_end pointer isn't properly initialized, but the log message in ngx_http_process_request_headers() hasn't been adjusted. It used the pointer in size calculation, which might result in up to 2k buffer over-read. Found with afl-fuzz. diffstat: src/http/ngx_http_request.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diffs (19 lines): diff -r cfc3cfa434ec -r 71edd9192f24 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Fri Feb 19 18:13:54 2016 +0300 +++ b/src/http/ngx_http_request.c Wed Feb 24 16:01:23 2016 +0300 @@ -1351,12 +1351,11 @@ ngx_http_process_request_headers(ngx_eve continue; } - /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */ + /* rc == NGX_HTTP_PARSE_INVALID_HEADER */ ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent invalid header line: \"%*s\\r...\"", - r->header_end - r->header_name_start, - r->header_name_start); + "client sent invalid header line"); + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; } From vbart at nginx.com Wed Feb 24 13:08:42 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 24 Feb 2016 13:08:42 +0000 Subject: [nginx] HTTP/2: cleaned up state while closing stream. Message-ID: details: http://hg.nginx.org/nginx/rev/c6ccc1ea9450 branches: changeset: 6410:c6ccc1ea9450 user: Valentin Bartenev date: Wed Feb 24 16:05:46 2016 +0300 description: HTTP/2: cleaned up state while closing stream. Without this the state might keep pointing to already closed stream. diffstat: src/http/v2/ngx_http_v2.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r 71edd9192f24 -r c6ccc1ea9450 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Wed Feb 24 16:01:23 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Wed Feb 24 16:05:46 2016 +0300 @@ -3661,6 +3661,10 @@ ngx_http_v2_close_stream(ngx_http_v2_str } } + if (h2c->state.stream == stream) { + h2c->state.stream = NULL; + } + node->stream = NULL; ngx_queue_insert_tail(&h2c->closed, &node->reuse); From vbart at nginx.com Wed Feb 24 13:08:44 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 24 Feb 2016 13:08:44 +0000 Subject: [nginx] HTTP/2: always use temporary pool for processing headers. Message-ID: details: http://hg.nginx.org/nginx/rev/8ec349bb60b2 branches: changeset: 6411:8ec349bb60b2 user: Valentin Bartenev date: Wed Feb 24 16:05:47 2016 +0300 description: HTTP/2: always use temporary pool for processing headers. This is required for implementing per request timeouts. Previously, the temporary pool was used only during skipping of headers and the request pool was used otherwise. That required switching of pools if the request was closed while parsing. It wasn't a problem since the request could be closed only after the validation of the fully parsed header. With the per request timeouts, the request can be closed at any moment, and switching of pools in the middle of parsing header name or value becomes a problem. To overcome this, the temporary pool is now always created and used. Special checks are added to keep it when either the stream is being processed or until header block is fully parsed. diffstat: src/http/v2/ngx_http_v2.c | 61 ++++++++++++++++++++++++++-------------------- src/http/v2/ngx_http_v2.h | 3 ++ 2 files changed, 38 insertions(+), 26 deletions(-) diffs (181 lines): diff -r c6ccc1ea9450 -r 8ec349bb60b2 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Wed Feb 24 16:05:46 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Wed Feb 24 16:05:47 2016 +0300 @@ -112,8 +112,6 @@ static u_char *ngx_http_v2_state_skip_pa u_char *pos, u_char *end); static u_char *ngx_http_v2_state_skip(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end); -static u_char *ngx_http_v2_state_skip_headers(ngx_http_v2_connection_t *h2c, - u_char *pos, u_char *end); static u_char *ngx_http_v2_state_save(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end, ngx_http_v2_handler_pt handler); static u_char *ngx_http_v2_connection_error(ngx_http_v2_connection_t *h2c, @@ -1133,6 +1131,11 @@ ngx_http_v2_state_headers(ngx_http_v2_co h2c->last_sid = h2c->state.sid; + h2c->state.pool = ngx_create_pool(1024, h2c->connection->log); + if (h2c->state.pool == NULL) { + return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); + } + if (depend == h2c->state.sid) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client sent HEADERS frame for stream %ui " @@ -1146,7 +1149,7 @@ ngx_http_v2_state_headers(ngx_http_v2_co NGX_HTTP_V2_INTERNAL_ERROR); } - return ngx_http_v2_state_skip_headers(h2c, pos, end); + return ngx_http_v2_state_header_block(h2c, pos, end); } h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, @@ -1166,7 +1169,7 @@ ngx_http_v2_state_headers(ngx_http_v2_co NGX_HTTP_V2_INTERNAL_ERROR); } - return ngx_http_v2_state_skip_headers(h2c, pos, end); + return ngx_http_v2_state_header_block(h2c, pos, end); } node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1); @@ -1185,6 +1188,11 @@ ngx_http_v2_state_headers(ngx_http_v2_co return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); } + h2c->state.stream = stream; + + stream->pool = h2c->state.pool; + h2c->state.keep_pool = 1; + stream->request->request_length = h2c->state.length; stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; @@ -1192,9 +1200,6 @@ ngx_http_v2_state_headers(ngx_http_v2_co node->stream = stream; - h2c->state.stream = stream; - h2c->state.pool = stream->request->pool; - if (priority || node->parent == NULL) { node->weight = weight; ngx_http_v2_set_dependency(h2c, node, depend, excl); @@ -1686,7 +1691,6 @@ ngx_http_v2_state_process_header(ngx_htt error: h2c->state.stream = NULL; - h2c->state.pool = NULL; return ngx_http_v2_state_header_complete(h2c, pos, end); } @@ -1699,8 +1703,7 @@ ngx_http_v2_state_header_complete(ngx_ht ngx_http_v2_stream_t *stream; if (h2c->state.length) { - h2c->state.handler = h2c->state.pool ? ngx_http_v2_state_header_block - : ngx_http_v2_state_skip_headers; + h2c->state.handler = ngx_http_v2_state_header_block; return pos; } @@ -1713,12 +1716,14 @@ ngx_http_v2_state_header_complete(ngx_ht if (stream) { ngx_http_v2_run_request(stream->request); - - } else if (h2c->state.pool) { + } + + if (!h2c->state.keep_pool) { ngx_destroy_pool(h2c->state.pool); } h2c->state.pool = NULL; + h2c->state.keep_pool = 0; if (h2c->state.padding) { return ngx_http_v2_state_skip_padded(h2c, pos, end); @@ -2337,19 +2342,6 @@ ngx_http_v2_state_skip(ngx_http_v2_conne static u_char * -ngx_http_v2_state_skip_headers(ngx_http_v2_connection_t *h2c, u_char *pos, - u_char *end) -{ - h2c->state.pool = ngx_create_pool(1024, h2c->connection->log); - if (h2c->state.pool == NULL) { - return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); - } - - return ngx_http_v2_state_header_block(h2c, pos, end); -} - - -static u_char * ngx_http_v2_state_save(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end, ngx_http_v2_handler_pt handler) { @@ -3633,6 +3625,7 @@ ngx_http_v2_terminate_stream(ngx_http_v2 void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc) { + ngx_pool_t *pool; ngx_event_t *ev; ngx_connection_t *fc; ngx_http_v2_node_t *node; @@ -3670,8 +3663,25 @@ ngx_http_v2_close_stream(ngx_http_v2_str ngx_queue_insert_tail(&h2c->closed, &node->reuse); h2c->closed_nodes++; + /* + * This pool keeps decoded request headers which can be used by log phase + * handlers in ngx_http_free_request(). + * + * The pointer is stored into local variable because the stream object + * will be destroyed after a call to ngx_http_free_request(). + */ + pool = stream->pool; + ngx_http_free_request(stream->request, rc); + if (pool != h2c->state.pool) { + ngx_destroy_pool(pool); + + } else { + /* pool will be destroyed when the complete header is parsed */ + h2c->state.keep_pool = 0; + } + ev = fc->read; if (ev->active || ev->disabled) { @@ -3825,7 +3835,6 @@ ngx_http_v2_finalize_connection(ngx_http if (h2c->state.stream) { h2c->state.stream->out_closed = 1; - h2c->state.pool = NULL; ngx_http_v2_close_stream(h2c->state.stream, NGX_HTTP_BAD_REQUEST); } diff -r c6ccc1ea9450 -r 8ec349bb60b2 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Wed Feb 24 16:05:46 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Wed Feb 24 16:05:47 2016 +0300 @@ -73,6 +73,7 @@ typedef struct { unsigned flags:8; unsigned incomplete:1; + unsigned keep_pool:1; /* HPACK */ unsigned parse_name:1; @@ -186,6 +187,8 @@ struct ngx_http_v2_stream_s { size_t header_limit; + ngx_pool_t *pool; + unsigned handled:1; unsigned blocked:1; unsigned exhausted:1; From vbart at nginx.com Wed Feb 24 13:08:47 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Wed, 24 Feb 2016 13:08:47 +0000 Subject: [nginx] HTTP/2: implemented per request timeouts (closes #626). Message-ID: details: http://hg.nginx.org/nginx/rev/4ba91a4c66a3 branches: changeset: 6412:4ba91a4c66a3 user: Valentin Bartenev date: Wed Feb 24 15:58:07 2016 +0300 description: HTTP/2: implemented per request timeouts (closes #626). Previously, there were only three timeouts used globally for the whole HTTP/2 connection: 1. Idle timeout for inactivity when there are no streams in processing (the "http2_idle_timeout" directive); 2. Receive timeout for incomplete frames when there are no streams in processing (the "http2_recv_timeout" directive); 3. Send timeout when there are frames waiting in the output queue (the "send_timeout" directive on a server level). Reaching one of these timeouts leads to HTTP/2 connection close. This left a number of scenarios when a connection can get stuck without any processing and timeouts: 1. A client has sent the headers block partially so nginx starts processing a new stream but cannot continue without the rest of HEADERS and/or CONTINUATION frames; 2. When nginx waits for the request body; 3. All streams are stuck on exhausted connection or stream windows. The first idea that was rejected was to detect when the whole connection gets stuck because of these situations and set the global receive timeout. The disadvantage of such approach would be inconsistent behaviour in some typical use cases. For example, if a user never replies to the browser's question about where to save the downloaded file, the stream will be eventually closed by a timeout. On the other hand, this will not happen if there's some activity in other concurrent streams. Now almost all the request timeouts work like in HTTP/1.x connections, so the "client_header_timeout", "client_body_timeout", and "send_timeout" are respected. These timeouts close the request. The global timeouts work as before. Previously, the c->write->delayed flag was abused to avoid setting timeouts on stream events. Now, the "active" and "ready" flags are manipulated instead to control the processing of individual streams. diffstat: src/http/ngx_http_request.c | 12 -- src/http/v2/ngx_http_v2.c | 176 ++++++++++++++++++++++++------- src/http/v2/ngx_http_v2_filter_module.c | 22 +-- 3 files changed, 147 insertions(+), 63 deletions(-) diffs (504 lines): diff -r 8ec349bb60b2 -r 4ba91a4c66a3 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Wed Feb 24 16:05:47 2016 +0300 +++ b/src/http/ngx_http_request.c Wed Feb 24 15:58:07 2016 +0300 @@ -2573,12 +2573,6 @@ ngx_http_set_write_handler(ngx_http_requ ngx_http_test_reading; r->write_event_handler = ngx_http_writer; -#if (NGX_HTTP_V2) - if (r->stream) { - return NGX_OK; - } -#endif - wev = r->connection->write; if (wev->ready && wev->delayed) { @@ -2664,12 +2658,6 @@ ngx_http_writer(ngx_http_request_t *r) if (r->buffered || r->postponed || (r == r->main && c->buffered)) { -#if (NGX_HTTP_V2) - if (r->stream) { - return; - } -#endif - if (!wev->delayed) { ngx_add_timer(wev, clcf->send_timeout); } diff -r 8ec349bb60b2 -r 4ba91a4c66a3 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Wed Feb 24 16:05:47 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Wed Feb 24 15:58:07 2016 +0300 @@ -114,6 +114,8 @@ static u_char *ngx_http_v2_state_skip(ng u_char *pos, u_char *end); static u_char *ngx_http_v2_state_save(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end, ngx_http_v2_handler_pt handler); +static u_char *ngx_http_v2_state_headers_save(ngx_http_v2_connection_t *h2c, + u_char *pos, u_char *end, ngx_http_v2_handler_pt handler); static u_char *ngx_http_v2_connection_error(ngx_http_v2_connection_t *h2c, ngx_uint_t err); @@ -162,6 +164,7 @@ static ngx_int_t ngx_http_v2_cookie(ngx_ static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r); static void ngx_http_v2_run_request(ngx_http_request_t *r); static ngx_int_t ngx_http_v2_init_request_body(ngx_http_request_t *r); +static void ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream, ngx_uint_t status); @@ -430,6 +433,10 @@ ngx_http_v2_write_handler(ngx_event_t *w "run http2 stream %ui", stream->node->id); wev = stream->request->connection->write; + + wev->active = 0; + wev->ready = 1; + wev->handler(wev); } @@ -883,6 +890,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_ ngx_buf_t *buf; ngx_int_t rc; ngx_temp_file_t *tf; + ngx_connection_t *fc; ngx_http_request_t *r; ngx_http_v2_stream_t *stream; ngx_http_request_body_t *rb; @@ -919,6 +927,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_ return ngx_http_v2_state_skip_padded(h2c, pos, end); } + fc = r->connection; rb = r->request_body; tf = rb->temp_file; buf = rb->buf; @@ -929,7 +938,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_ if (r->headers_in.content_length_n != -1 && r->headers_in.content_length_n < rb->rest) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client intended to send body data " "larger than declared"); @@ -942,7 +951,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_ if (clcf->client_max_body_size && clcf->client_max_body_size < rb->rest) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + ngx_log_error(NGX_LOG_ERR, fc->log, 0, "client intended to send " "too large chunked body: %O bytes", rb->rest); @@ -982,6 +991,11 @@ ngx_http_v2_state_read_data(ngx_http_v2_ } if (h2c->state.length) { + if (rb->post_handler) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ngx_add_timer(fc->read, clcf->client_body_timeout); + } + return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_read_data); } @@ -993,7 +1007,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_ r->headers_in.content_length_n = rb->rest; } else if (r->headers_in.content_length_n != rb->rest) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client prematurely closed stream: " "only %O out of %O bytes of request body received", rb->rest, r->headers_in.content_length_n); @@ -1013,9 +1027,17 @@ ngx_http_v2_state_read_data(ngx_http_v2_ } if (rb->post_handler) { + if (fc->read->timer_set) { + ngx_del_timer(fc->read); + } + r->read_event_handler = ngx_http_block_reading; rb->post_handler(r); } + + } else if (rb->post_handler) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ngx_add_timer(fc->read, clcf->client_body_timeout); } if (h2c->state.padding) { @@ -1027,6 +1049,9 @@ ngx_http_v2_state_read_data(ngx_http_v2_ error: if (rb->post_handler) { + if (fc->read->timer_set) { + ngx_del_timer(fc->read); + } if (stream->skip_data == NGX_HTTP_V2_DATA_ERROR) { rc = (r->headers_in.content_length_n == -1) @@ -1218,8 +1243,8 @@ ngx_http_v2_state_header_block(ngx_http_ ngx_uint_t indexed, size_update, prefix; if (end - pos < 1) { - return ngx_http_v2_state_save(h2c, pos, end, - ngx_http_v2_state_header_block); + return ngx_http_v2_state_headers_save(h2c, pos, end, + ngx_http_v2_state_header_block); } if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) @@ -1262,8 +1287,8 @@ ngx_http_v2_state_header_block(ngx_http_ if (value < 0) { if (value == NGX_AGAIN) { - return ngx_http_v2_state_save(h2c, pos, end, - ngx_http_v2_state_header_block); + return ngx_http_v2_state_headers_save(h2c, pos, end, + ngx_http_v2_state_header_block); } if (value == NGX_DECLINED) { @@ -1333,8 +1358,8 @@ ngx_http_v2_state_field_len(ngx_http_v2_ } if (end - pos < 1) { - return ngx_http_v2_state_save(h2c, pos, end, - ngx_http_v2_state_field_len); + return ngx_http_v2_state_headers_save(h2c, pos, end, + ngx_http_v2_state_field_len); } huff = *pos >> 7; @@ -1342,8 +1367,8 @@ ngx_http_v2_state_field_len(ngx_http_v2_ if (len < 0) { if (len == NGX_AGAIN) { - return ngx_http_v2_state_save(h2c, pos, end, - ngx_http_v2_state_field_len); + return ngx_http_v2_state_headers_save(h2c, pos, end, + ngx_http_v2_state_field_len); } if (len == NGX_DECLINED) { @@ -1435,8 +1460,8 @@ ngx_http_v2_state_field_huff(ngx_http_v2 } if (h2c->state.length) { - return ngx_http_v2_state_save(h2c, pos, end, - ngx_http_v2_state_field_huff); + return ngx_http_v2_state_headers_save(h2c, pos, end, + ngx_http_v2_state_field_huff); } if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) { @@ -1480,8 +1505,8 @@ ngx_http_v2_state_field_raw(ngx_http_v2_ } if (h2c->state.length) { - return ngx_http_v2_state_save(h2c, pos, end, - ngx_http_v2_state_field_raw); + return ngx_http_v2_state_headers_save(h2c, pos, end, + ngx_http_v2_state_field_raw); } if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) { @@ -1754,7 +1779,7 @@ ngx_http_v2_handle_continuation(ngx_http } if ((size_t) (end - pos) < len + NGX_HTTP_V2_FRAME_HEADER_SIZE) { - return ngx_http_v2_state_save(h2c, pos, end, handler); + return ngx_http_v2_state_headers_save(h2c, pos, end, handler); } p = pos + len; @@ -2229,8 +2254,10 @@ ngx_http_v2_state_window_update(ngx_http wev = stream->request->connection->write; - if (!wev->timer_set) { - wev->delayed = 0; + wev->active = 0; + wev->ready = 1; + + if (!wev->delayed) { wev->handler(wev); } } @@ -2262,8 +2289,10 @@ ngx_http_v2_state_window_update(ngx_http wev = stream->request->connection->write; - if (!wev->timer_set) { - wev->delayed = 0; + wev->active = 0; + wev->ready = 1; + + if (!wev->delayed) { wev->handler(wev); if (h2c->send_window == 0) { @@ -2371,6 +2400,28 @@ ngx_http_v2_state_save(ngx_http_v2_conne static u_char * +ngx_http_v2_state_headers_save(ngx_http_v2_connection_t *h2c, u_char *pos, + u_char *end, ngx_http_v2_handler_pt handler) +{ + ngx_event_t *rev; + ngx_http_request_t *r; + ngx_http_core_srv_conf_t *cscf; + + if (h2c->state.stream) { + r = h2c->state.stream->request; + rev = r->connection->read; + + if (!rev->timer_set) { + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + ngx_add_timer(rev, cscf->client_header_timeout); + } + } + + return ngx_http_v2_state_save(h2c, pos, end, handler); +} + + +static u_char * ngx_http_v2_connection_error(ngx_http_v2_connection_t *h2c, ngx_uint_t err) { @@ -2748,6 +2799,7 @@ ngx_http_v2_create_stream(ngx_http_v2_co ngx_memcpy(log, h2c->connection->log, sizeof(ngx_log_t)); log->data = ctx; + log->action = "reading client request headers"; ngx_memzero(rev, sizeof(ngx_event_t)); @@ -3554,7 +3606,8 @@ ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r, ngx_http_client_body_handler_pt post_handler) { - ngx_http_v2_stream_t *stream; + ngx_http_v2_stream_t *stream; + ngx_http_core_loc_conf_t *clcf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http2 read request body"); @@ -3590,13 +3643,48 @@ ngx_http_v2_read_request_body(ngx_http_r r->request_body->post_handler = post_handler; - r->read_event_handler = ngx_http_test_reading; + r->read_event_handler = ngx_http_v2_read_client_request_body_handler; r->write_event_handler = ngx_http_request_empty_handler; + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ngx_add_timer(r->connection->read, clcf->client_body_timeout); + return NGX_AGAIN; } +static void +ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r) +{ + ngx_connection_t *fc; + + fc = r->connection; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 read client request body handler"); + + if (fc->read->timedout) { + ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out"); + + fc->timedout = 1; + r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD; + + ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); + return; + } + + if (fc->error) { + ngx_log_error(NGX_LOG_INFO, fc->log, 0, + "client prematurely closed stream"); + + r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD; + + ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST); + return; + } +} + + static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream, ngx_uint_t status) @@ -3647,7 +3735,8 @@ ngx_http_v2_close_stream(ngx_http_v2_str if (!stream->out_closed) { if (ngx_http_v2_send_rst_stream(h2c, node->id, - NGX_HTTP_V2_INTERNAL_ERROR) + fc->timedout ? NGX_HTTP_V2_PROTOCOL_ERROR + : NGX_HTTP_V2_INTERNAL_ERROR) != NGX_OK) { h2c->connection->error = 1; @@ -3684,11 +3773,6 @@ ngx_http_v2_close_stream(ngx_http_v2_str ev = fc->read; - if (ev->active || ev->disabled) { - ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0, - "fake read event was activated"); - } - if (ev->timer_set) { ngx_del_timer(ev); } @@ -3699,11 +3783,6 @@ ngx_http_v2_close_stream(ngx_http_v2_str ev = fc->write; - if (ev->active || ev->disabled) { - ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0, - "fake write event was activated"); - } - if (ev->timer_set) { ngx_del_timer(ev); } @@ -3737,9 +3816,18 @@ ngx_http_v2_close_stream_handler(ngx_eve fc = ev->data; r = fc->data; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, "http2 close stream handler"); + if (ev->timedout) { + ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out"); + + fc->timedout = 1; + + ngx_http_v2_close_stream(r->stream, NGX_HTTP_REQUEST_TIME_OUT); + return; + } + ngx_http_v2_close_stream(r->stream, 0); } @@ -3747,7 +3835,11 @@ ngx_http_v2_close_stream_handler(ngx_eve static void ngx_http_v2_handle_connection_handler(ngx_event_t *rev) { - ngx_connection_t *c; + ngx_connection_t *c; + ngx_http_v2_connection_t *h2c; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, + "http2 handle connection handler"); rev->handler = ngx_http_v2_read_handler; @@ -3757,6 +3849,12 @@ ngx_http_v2_handle_connection_handler(ng } c = rev->data; + h2c = c->data; + + if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { + ngx_http_v2_finalize_connection(h2c, 0); + return; + } ngx_http_v2_handle_connection(c->data); } @@ -3878,9 +3976,7 @@ ngx_http_v2_finalize_connection(ngx_http if (stream->queued) { stream->queued = 0; - ev = fc->write; - ev->delayed = 0; } else { ev = fc->read; @@ -3949,8 +4045,10 @@ ngx_http_v2_adjust_windows(ngx_http_v2_c wev = stream->request->connection->write; - if (!wev->timer_set) { - wev->delayed = 0; + wev->active = 0; + wev->ready = 1; + + if (!wev->delayed) { wev->handler(wev); } } diff -r 8ec349bb60b2 -r 4ba91a4c66a3 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Wed Feb 24 16:05:47 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Wed Feb 24 15:58:07 2016 +0300 @@ -799,7 +799,9 @@ ngx_http_v2_send_chain(ngx_connection_t if (in == NULL) { if (stream->queued) { - fc->write->delayed = 1; + fc->write->active = 1; + fc->write->ready = 0; + } else { fc->buffered &= ~NGX_HTTP_V2_BUFFERED; } @@ -810,7 +812,8 @@ ngx_http_v2_send_chain(ngx_connection_t h2c = stream->connection; if (size && ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) { - fc->write->delayed = 1; + fc->write->active = 1; + fc->write->ready = 0; return in; } @@ -947,7 +950,8 @@ ngx_http_v2_send_chain(ngx_connection_t } if (in && ngx_http_v2_flow_control(h2c, stream) == NGX_DECLINED) { - fc->write->delayed = 1; + fc->write->active = 1; + fc->write->ready = 0; } return in; @@ -1078,7 +1082,8 @@ ngx_http_v2_filter_send(ngx_connection_t if (stream->queued) { fc->buffered |= NGX_HTTP_V2_BUFFERED; - fc->write->delayed = 1; + fc->write->active = 1; + fc->write->ready = 0; return NGX_AGAIN; } @@ -1316,14 +1321,7 @@ ngx_http_v2_handle_stream(ngx_http_v2_co wev = stream->request->connection->write; - /* - * This timer can only be set if the stream was delayed because of rate - * limit. In that case the event should be triggered by the timer. - */ - - if (!wev->timer_set) { - wev->delayed = 0; - + if (!wev->delayed) { stream->handled = 1; ngx_queue_insert_tail(&h2c->posted, &stream->queue); } From mdounin at mdounin.ru Wed Feb 24 15:03:09 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 24 Feb 2016 15:03:09 +0000 Subject: [nginx] nginx-1.9.12-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/ead3907d74f9 branches: changeset: 6413:ead3907d74f9 user: Maxim Dounin date: Wed Feb 24 17:53:22 2016 +0300 description: nginx-1.9.12-RELEASE diffstat: docs/xml/nginx/changes.xml | 102 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 102 insertions(+), 0 deletions(-) diffs (112 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,108 @@ + + + + +??????????? ???????? ?????????? ??????? ? HTTP/2.
+??????? ????? ????????. +
+ +Huffman encoding of response headers in HTTP/2.
+Thanks to Vlad Krasnov. +
+
+ + + +????????? worker_cpu_affinity ?????? ???????????? ????? 64 ???????????. + + +the "worker_cpu_affinity" directive now supports more than 64 CPUs. + + + + + +????????????? ?? ?????????? ???????? ?? C++; +?????? ????????? ? 1.9.11.
+??????? Piotr Sikora. +
+ +compatibility with 3rd party C++ modules; +the bug had appeared in 1.9.11.
+Thanks to Piotr Sikora. +
+
+ + + +nginx ?? ????????? ?????????? ? OpenSSL ?? Linux; +?????? ????????? ? 1.9.11. + + +nginx could not be built statically with OpenSSL on Linux; +the bug had appeared in 1.9.11. + + + + + +????????? "add_header ... always" ? ?????? ????????? +?? ??????? ?? ?????????? ????????? ??????? +?????? Last-Modified ? ETag. + + +the "add_header ... always" directive with an empty value +did not delete "Last-Modified" and "ETag" header lines +from error responses. + + + + + +??? ????????????? OpenSSL 1.0.2f ? ????? ????? ?????????? +????????? "called a function you should not call" ? +"shutdown while in init". + + +"called a function you should not call" +and "shutdown while in init" messages might appear in logs +when using OpenSSL 1.0.2f. + + + + + +????????? ????????? ????? ????????????? ???????????. + + +invalid headers might be logged incorrectly. + + + + + +?????? ??????? ??? ????????????? HTTP/2. + + +socket leak when using HTTP/2. + + + + + +? ?????? ngx_http_v2_module. + + +in the ngx_http_v2_module. + + + +
+ + From mdounin at mdounin.ru Wed Feb 24 15:03:11 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 24 Feb 2016 15:03:11 +0000 Subject: [nginx] release-1.9.12 tag Message-ID: details: http://hg.nginx.org/nginx/rev/fbd5d6c19798 branches: changeset: 6414:fbd5d6c19798 user: Maxim Dounin date: Wed Feb 24 17:53:23 2016 +0300 description: release-1.9.12 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -394,3 +394,4 @@ 1bdc497c81607d854e3edf8b9a3be324c3d136b6 ef107f3ddc237a3007e2769ec04adde0dcf627fa release-1.9.9 be00ca08e41a69e585b6aff70a725ed6c9e1a876 release-1.9.10 fe66cff450a95beed36a2515210eb2d7ef62c9d3 release-1.9.11 +ead3907d74f90a14d1646f1b2b56ba01d3d11702 release-1.9.12 From agentzh at gmail.com Thu Feb 25 07:59:19 2016 From: agentzh at gmail.com (Yichun Zhang (agentzh)) Date: Wed, 24 Feb 2016 23:59:19 -0800 Subject: [ANN] Test::Nginx 0.25 released Message-ID: Hi guys, I've just uploaded Test::Nginx 0.25 to CPAN: https://metacpan.org/release/Test-Nginx It will appear on the CPAN mirror near you in the next few hours or so. Special thanks go to all our contributors and users :) Here's the complete change log for this release (compared to the last CPAN release, 0.24): * feature: added the new test mdoule, Test::Nginx::Socket::Lua::Stream, for testing stream-typed NGINX C modules like ngx_stream_echo_module and ngx_stream_lua_module. Please see https://metacpan.org/pod/Test::Nginx::Socket::Lua::Stream for more details. * feature: added new section "--- server_addr_for_client" to control the value of server_addr for client. thanks Guanlan Dai for the patch. * feature: added support for the TEST_NGINX_LOAD_MODULES environment for loading dynamic NGINX modules in nginx.conf globally. * feature: added support for ASAN by passing ASAN_OPTIONS environment variable. thanks Markus Linnala for the patch. * feature: Test::Nginx::Socket::Lua: added support for the init_by_lua_block {} directive of ngx_http_lua_module. * feature: avoided variations in the absolute line numbers of user configurations so that the test cases can check nginx configuration file line numbers deterministically. * feature: implemented the env_to_nginx() Perl utility function as per Rollin Crittendon's request. for example: env_to_nginx('foo', 'bar=hello world') * feature: now we pass the environment DYLD_FORCE_FLAT_NAMESPACE to the nginx by default as well. * feature: implemented the "--- todo" section for TODOing test blocks. thanks Markus Linnala for the patch. * feature: repeat_each() also returns the value even when it is used as a setter. * bugfix: testing could not continue properly when the "--- must_die" subtest failed. * bugfix: ARRAY-typed "--- more_headers" now work with ARRAY-typed "--- request". thanks Kipras Mancevi?ius for the report. * bugfix: fixed the perl warning "Use of uninitialized value $val in concatenation" when "--- more_headers" has headers without values. * bugfix: use SIGTERM to kill non-responsive nginx/valgrind processes instead of SIGQUIT; otherwise the perl test process may hang forever in valgrind testing mode. * bugfix: only complain about failures of removing the nginx pid file when it still exists. * bugfix: we should bail out when `nginx -V` returns anything that we cannot understand. * bugfix: builtin udp server: fixed recv() call's error handling. * bugfix: we did not expand environments TEST_NGINX_XXX in the "--- main_config" and "--- post_main_config" data sections. * bugfix: better error handling in the mocked UDP server. * change: changed the default value of TEST_NGINX_SLEEP to 0.015 (sec). thanks Dejiang Zhu for the patch. * improvement: output the system error message when failing to remove the nginx pid file. * improvement: made the error_log test failure message clearer. thanks Nick Muerdter for the patch. * doc: fixed the module description of Test::Nginx and Test::Nginx::Socket to reflect recent changes. * doc: now we highly recommend Test::Nginx::Socket and its subclasses. * doc: documentged the default timeout value used by the client. thanks Nick Muerdter for the patch. * doc: added a link to the official user guide in the book "Programming OpenResty". This Perl module provides a test scaffold based on IO::Socket for automated testing in Nginx C module or ngx_lua-based Lua library development. This class inherits from Test::Base, thus bringing all its declarative power to the NginxC module testing practices. Please check out the full documentation on CPAN: https://metacpan.org/pod/Test::Nginx::Socket as well as the official user guide in the book "Programming OpenResty": https://openresty.gitbooks.io/programming-openresty/content/testing/ All of our Nginx modules (as well as our lua-resty-* libraries) are using Test::Nginx to drive their test suites. And it is also driving my test cluster running on Amazon EC2: http://qa.openresty.org Please note that this module is completely different from the Test::Nginx module created by Maxim Dounin. The git repository for this Perl module is hosted on GitHub: https://github.com/openresty/test-nginx Have fun! Best regards, -agentzh From ru at nginx.com Thu Feb 25 13:29:22 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 25 Feb 2016 13:29:22 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/107a46bde349 branches: changeset: 6415:107a46bde349 user: Ruslan Ermilov date: Thu Feb 25 16:28:42 2016 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r fbd5d6c19798 -r 107a46bde349 src/core/nginx.h --- a/src/core/nginx.h Wed Feb 24 17:53:23 2016 +0300 +++ b/src/core/nginx.h Thu Feb 25 16:28:42 2016 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1009012 -#define NGINX_VERSION "1.9.12" +#define nginx_version 1009013 +#define NGINX_VERSION "1.9.13" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From ru at nginx.com Thu Feb 25 13:29:24 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 25 Feb 2016 13:29:24 +0000 Subject: [nginx] Dynamic modules: make sure to call config.make for dynamic addons. Message-ID: details: http://hg.nginx.org/nginx/rev/35487ea55cb6 branches: changeset: 6416:35487ea55cb6 user: Ruslan Ermilov date: Thu Feb 25 15:22:05 2016 +0300 description: Dynamic modules: make sure to call config.make for dynamic addons. diffstat: auto/make | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (15 lines): diff -r 107a46bde349 -r 35487ea55cb6 auto/make --- a/auto/make Thu Feb 25 16:28:42 2016 +0300 +++ b/auto/make Thu Feb 25 15:22:05 2016 +0300 @@ -437,9 +437,9 @@ fi # the addons config.make -if test -n "$NGX_ADDONS"; then +if test -n "$NGX_ADDONS$DYNAMIC_ADDONS"; then - for ngx_addon_dir in $NGX_ADDONS + for ngx_addon_dir in $NGX_ADDONS $DYNAMIC_ADDONS do if test -f $ngx_addon_dir/config.make; then . $ngx_addon_dir/config.make From ru at nginx.com Thu Feb 25 13:30:04 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 25 Feb 2016 13:30:04 +0000 Subject: [nginx] Dynamic modules: removed unnecessary initialization. Message-ID: details: http://hg.nginx.org/nginx/rev/ce946e0976dc branches: changeset: 6417:ce946e0976dc user: Ruslan Ermilov date: Thu Feb 25 16:29:51 2016 +0300 description: Dynamic modules: removed unnecessary initialization. It became unnecessary after 85dea406e18f. diffstat: src/core/ngx_module.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 35487ea55cb6 -r ce946e0976dc src/core/ngx_module.c --- a/src/core/ngx_module.c Thu Feb 25 15:22:05 2016 +0300 +++ b/src/core/ngx_module.c Thu Feb 25 16:29:51 2016 +0300 @@ -27,7 +27,6 @@ ngx_preinit_modules() { ngx_uint_t i; - ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]->index = i; ngx_modules[i]->name = ngx_module_names[i]; From vbart at nginx.com Fri Feb 26 15:45:55 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Fri, 26 Feb 2016 18:45:55 +0300 Subject: [PATCH 0 of 4] Support for unbuffered upload in HTTP/2 Message-ID: This patch series adds support of swithing off buffering for request body in HTTP/2 connections proxied to backend. See proxy_request_buffering, fastcgi_request_buffering, uwsgi_request_buffering, and scgi_request_buffering directives. You can appliy these patches to nginx 1.9.12. Thank you for testing. wbr, Valentin V. Bartenev src/http/ngx_http_request_body.c | 109 ++---- src/http/ngx_http_request.h | 3 + src/http/ngx_http_request_body.c | 26 +- src/http/v2/ngx_http_v2.c | 541 ++++++++++++++++++-------------------- src/http/v2/ngx_http_v2.h | 3 +- src/http/v2/ngx_http_v2.c | 15 +- src/http/ngx_http_request_body.c | 7 +- src/http/v2/ngx_http_v2.c | 132 +++++++++- src/http/v2/ngx_http_v2.h | 1 + 9 files changed, 466 insertions(+), 371 deletions(-) From vbart at nginx.com Fri Feb 26 15:45:56 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Fri, 26 Feb 2016 18:45:56 +0300 Subject: [PATCH 1 of 4] Request body: moved handling of the last part in the save filter In-Reply-To: References: Message-ID: <1f4781e6b9043414d0c8.1456501556@localhost> src/http/ngx_http_request_body.c | 109 ++++++++++++++------------------------ 1 files changed, 40 insertions(+), 69 deletions(-) # HG changeset patch # User Valentin Bartenev # Date 1456486790 -10800 # Fri Feb 26 14:39:50 2016 +0300 # Node ID 1f4781e6b9043414d0c8ec7884f31f7e033b14c6 # Parent ce946e0976dc9750b06a06b91ff58595cf36bd62 Request body: moved handling of the last part in the save filter. No functional changes. diff -r ce946e0976dc -r 1f4781e6b904 src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Thu Feb 25 16:29:51 2016 +0300 +++ b/src/http/ngx_http_request_body.c Fri Feb 26 14:39:50 2016 +0300 @@ -34,7 +34,7 @@ ngx_http_read_client_request_body(ngx_ht ssize_t size; ngx_int_t rc; ngx_buf_t *b; - ngx_chain_t out, *cl; + ngx_chain_t out; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; @@ -59,10 +59,6 @@ ngx_http_read_client_request_body(ngx_ht goto done; } - if (r->request_body_no_buffering) { - r->request_body_in_file_only = 0; - } - rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); if (rb == NULL) { rc = NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -148,37 +144,8 @@ ngx_http_read_client_request_body(ngx_ht if (rb->rest == 0) { /* the whole request body was pre-read */ - - if (r->request_body_in_file_only) { - if (ngx_http_write_request_body(r) != NGX_OK) { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; - goto done; - } - - if (rb->temp_file->file.offset != 0) { - - cl = ngx_chain_get_free_buf(r->pool, &rb->free); - if (cl == NULL) { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; - goto done; - } - - b = cl->buf; - - ngx_memzero(b, sizeof(ngx_buf_t)); - - b->in_file = 1; - b->file_last = rb->temp_file->file.offset; - b->file = &rb->temp_file->file; - - rb->bufs = cl; - } - } - r->request_body_no_buffering = 0; - post_handler(r); - return NGX_OK; } @@ -289,8 +256,7 @@ ngx_http_do_read_client_request_body(ngx size_t size; ssize_t n; ngx_int_t rc; - ngx_buf_t *b; - ngx_chain_t *cl, out; + ngx_chain_t out; ngx_connection_t *c; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; @@ -439,33 +405,6 @@ ngx_http_do_read_client_request_body(ngx ngx_del_timer(c->read); } - if (rb->temp_file || r->request_body_in_file_only) { - - /* save the last part */ - - if (ngx_http_write_request_body(r) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (rb->temp_file->file.offset != 0) { - - cl = ngx_chain_get_free_buf(r->pool, &rb->free); - if (cl == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - b = cl->buf; - - ngx_memzero(b, sizeof(ngx_buf_t)); - - b->in_file = 1; - b->file_last = rb->temp_file->file.offset; - b->file = &rb->temp_file->file; - - rb->bufs = cl; - } - } - if (!r->request_body_no_buffering) { r->read_event_handler = ngx_http_block_reading; rb->post_handler(r); @@ -1127,9 +1066,8 @@ ngx_http_request_body_chunked_filter(ngx ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) { -#if (NGX_DEBUG) + ngx_buf_t *b; ngx_chain_t *cl; -#endif ngx_http_request_body_t *rb; rb = r->request_body; @@ -1166,13 +1104,46 @@ ngx_http_request_body_save_filter(ngx_ht return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (rb->rest > 0 - && rb->buf && rb->buf->last == rb->buf->end - && !r->request_body_no_buffering) - { + if (r->request_body_no_buffering) { + return NGX_OK; + } + + if (rb->rest > 0) { + + if (rb->buf && rb->buf->last == rb->buf->end + && ngx_http_write_request_body(r) != NGX_OK) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + return NGX_OK; + } + + /* rb->rest == 0 */ + + if (rb->temp_file || r->request_body_in_file_only) { + if (ngx_http_write_request_body(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } + + if (rb->temp_file->file.offset != 0) { + + cl = ngx_chain_get_free_buf(r->pool, &rb->free); + if (cl == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + b = cl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + + b->in_file = 1; + b->file_last = rb->temp_file->file.offset; + b->file = &rb->temp_file->file; + + rb->bufs = cl; + } } return NGX_OK; From vbart at nginx.com Fri Feb 26 15:45:57 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Fri, 26 Feb 2016 18:45:57 +0300 Subject: [PATCH 2 of 4] HTTP/2: rewritten handling of request body In-Reply-To: References: Message-ID: src/http/ngx_http_request.h | 3 + src/http/ngx_http_request_body.c | 26 +- src/http/v2/ngx_http_v2.c | 541 ++++++++++++++++++-------------------- src/http/v2/ngx_http_v2.h | 3 +- 4 files changed, 279 insertions(+), 294 deletions(-) # HG changeset patch # User Valentin Bartenev # Date 1456498922 -10800 # Fri Feb 26 18:02:02 2016 +0300 # Node ID edacc9766e8e7f610921f71739e6797f771cf2b6 # Parent 1f4781e6b9043414d0c8ec7884f31f7e033b14c6 HTTP/2: rewritten handling of request body. There are two improvements: 1. Support for request body filters; 2. Receiving of request body is started only after the ngx_http_read_client_request_body() call. The last one fixes the problem when the client_max_body_size value might not be respected from the right location if the location was changed either during the process of receiving body or after the whole body had been received. diff -r 1f4781e6b904 -r edacc9766e8e src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Fri Feb 26 14:39:50 2016 +0300 +++ b/src/http/ngx_http_request.h Fri Feb 26 18:02:02 2016 +0300 @@ -284,6 +284,9 @@ typedef struct { ngx_chain_t *bufs; ngx_buf_t *buf; off_t rest; +#if (NGX_HTTP_V2) + off_t received; +#endif ngx_chain_t *free; ngx_chain_t *busy; ngx_http_chunked_t *chunked; diff -r 1f4781e6b904 -r edacc9766e8e src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Fri Feb 26 14:39:50 2016 +0300 +++ b/src/http/ngx_http_request_body.c Fri Feb 26 18:02:02 2016 +0300 @@ -40,20 +40,20 @@ ngx_http_read_client_request_body(ngx_ht r->main->count++; + if (r != r->main || r->request_body || r->discard_body) { + r->request_body_no_buffering = 0; + post_handler(r); + return NGX_OK; + } + #if (NGX_HTTP_V2) - if (r->stream && r == r->main) { + if (r->stream) { r->request_body_no_buffering = 0; rc = ngx_http_v2_read_request_body(r, post_handler); goto done; } #endif - if (r != r->main || r->request_body || r->discard_body) { - r->request_body_no_buffering = 0; - post_handler(r); - return NGX_OK; - } - if (ngx_http_test_expect(r) != NGX_OK) { rc = NGX_HTTP_INTERNAL_SERVER_ERROR; goto done; @@ -503,17 +503,17 @@ ngx_http_discard_request_body(ngx_http_r ngx_int_t rc; ngx_event_t *rev; + if (r != r->main || r->discard_body || r->request_body) { + return NGX_OK; + } + #if (NGX_HTTP_V2) - if (r->stream && r == r->main) { - r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD; + if (r->stream) { + r->stream->skip_data = 1; return NGX_OK; } #endif - if (r != r->main || r->discard_body || r->request_body) { - return NGX_OK; - } - if (ngx_http_test_expect(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff -r 1f4781e6b904 -r edacc9766e8e src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Feb 26 14:39:50 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Feb 26 18:02:02 2016 +0300 @@ -51,6 +51,8 @@ #define NGX_HTTP_V2_MAX_WINDOW ((1U << 31) - 1) #define NGX_HTTP_V2_DEFAULT_WINDOW 65535 +#define NGX_HTTP_V2_INITIAL_WINDOW 0 + #define NGX_HTTP_V2_ROOT (void *) -1 @@ -163,7 +165,10 @@ static ngx_int_t ngx_http_v2_cookie(ngx_ ngx_http_v2_header_t *header); static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r); static void ngx_http_v2_run_request(ngx_http_request_t *r); -static ngx_int_t ngx_http_v2_init_request_body(ngx_http_request_t *r); +static ngx_int_t ngx_http_v2_account_request_body(ngx_http_request_t *r, + size_t size, ngx_uint_t last); +static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r, + u_char *pos, size_t size, ngx_uint_t last); static void ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c, @@ -754,6 +759,7 @@ ngx_http_v2_state_head(ngx_http_v2_conne static u_char * ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { + ngx_int_t rc; ngx_http_v2_node_t *node; ngx_http_v2_stream_t *stream; @@ -845,8 +851,9 @@ ngx_http_v2_state_data(ngx_http_v2_conne stream->recv_window -= h2c->state.length; - if (stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) { - + if (stream->no_flow_control + && stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) + { if (ngx_http_v2_send_window_update(h2c, node->id, NGX_HTTP_V2_MAX_WINDOW - stream->recv_window) @@ -875,6 +882,16 @@ 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; + + rc = ngx_http_v2_account_request_body(stream->request, h2c->state.length, + stream->in_closed); + if (rc != NGX_OK) { + stream->skip_data = 1; + ngx_http_finalize_request(stream->request, rc); + return ngx_http_v2_state_skip_padded(h2c, pos, end); + } + h2c->state.stream = stream; return ngx_http_v2_state_read_data(h2c, pos, end); @@ -885,16 +902,10 @@ static u_char * ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { - size_t size; - ssize_t n; - ngx_buf_t *buf; - ngx_int_t rc; - ngx_temp_file_t *tf; - ngx_connection_t *fc; - ngx_http_request_t *r; - ngx_http_v2_stream_t *stream; - ngx_http_request_body_t *rb; - ngx_http_core_loc_conf_t *clcf; + size_t size; + ngx_int_t rc; + ngx_uint_t last; + ngx_http_v2_stream_t *stream; stream = h2c->state.stream; @@ -903,168 +914,39 @@ ngx_http_v2_state_read_data(ngx_http_v2_ } if (stream->skip_data) { - stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "skipping http2 DATA frame, reason: %d", - stream->skip_data); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "skipping http2 DATA frame"); return ngx_http_v2_state_skip_padded(h2c, pos, end); } + last = 0; size = end - pos; - if (size > h2c->state.length) { + if (size >= h2c->state.length) { size = h2c->state.length; - } - - r = stream->request; - - if (r->request_body == NULL - && ngx_http_v2_init_request_body(r) != NGX_OK) - { - stream->skip_data = NGX_HTTP_V2_DATA_INTERNAL_ERROR; - return ngx_http_v2_state_skip_padded(h2c, pos, end); - } - - fc = r->connection; - rb = r->request_body; - tf = rb->temp_file; - buf = rb->buf; - - if (size) { - rb->rest += size; - - if (r->headers_in.content_length_n != -1 - && r->headers_in.content_length_n < rb->rest) - { - ngx_log_error(NGX_LOG_INFO, fc->log, 0, - "client intended to send body data " - "larger than declared"); - - stream->skip_data = NGX_HTTP_V2_DATA_ERROR; - goto error; - - } else { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (clcf->client_max_body_size - && clcf->client_max_body_size < rb->rest) - { - ngx_log_error(NGX_LOG_ERR, fc->log, 0, - "client intended to send " - "too large chunked body: %O bytes", rb->rest); - - stream->skip_data = NGX_HTTP_V2_DATA_ERROR; - goto error; - } - } - - h2c->state.length -= size; - - if (tf) { - buf->start = pos; - buf->pos = pos; - - pos += size; - - buf->end = pos; - buf->last = pos; - - n = ngx_write_chain_to_temp_file(tf, rb->bufs); - - /* TODO: n == 0 or not complete and level event */ - - if (n == NGX_ERROR) { - stream->skip_data = NGX_HTTP_V2_DATA_INTERNAL_ERROR; - goto error; - } - - tf->offset += n; - - } else { - buf->last = ngx_cpymem(buf->last, pos, size); - pos += size; - } - - r->request_length += size; - } + last = stream->in_closed; + } + + rc = ngx_http_v2_process_request_body(stream->request, pos, size, last); + if (rc != NGX_OK) { + stream->skip_data = 1; + ngx_http_finalize_request(stream->request, rc); + } + + pos += size; + h2c->state.length -= size; if (h2c->state.length) { - if (rb->post_handler) { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_add_timer(fc->read, clcf->client_body_timeout); - } - return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_read_data); } - if (h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG) { - stream->in_closed = 1; - - if (r->headers_in.content_length_n < 0) { - r->headers_in.content_length_n = rb->rest; - - } else if (r->headers_in.content_length_n != rb->rest) { - ngx_log_error(NGX_LOG_INFO, fc->log, 0, - "client prematurely closed stream: " - "only %O out of %O bytes of request body received", - rb->rest, r->headers_in.content_length_n); - - stream->skip_data = NGX_HTTP_V2_DATA_ERROR; - goto error; - } - - if (tf) { - ngx_memzero(buf, sizeof(ngx_buf_t)); - - buf->in_file = 1; - buf->file_last = tf->file.offset; - buf->file = &tf->file; - - rb->buf = NULL; - } - - if (rb->post_handler) { - if (fc->read->timer_set) { - ngx_del_timer(fc->read); - } - - r->read_event_handler = ngx_http_block_reading; - rb->post_handler(r); - } - - } else if (rb->post_handler) { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_add_timer(fc->read, clcf->client_body_timeout); - } - if (h2c->state.padding) { return ngx_http_v2_state_skip_padded(h2c, pos, end); } return ngx_http_v2_state_complete(h2c, pos, end); - -error: - - if (rb->post_handler) { - if (fc->read->timer_set) { - ngx_del_timer(fc->read); - } - - if (stream->skip_data == NGX_HTTP_V2_DATA_ERROR) { - rc = (r->headers_in.content_length_n == -1) - ? NGX_HTTP_REQUEST_ENTITY_TOO_LARGE : NGX_HTTP_BAD_REQUEST; - - } else { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - ngx_http_finalize_request(r, rc); - } - - return ngx_http_v2_state_skip_padded(h2c, pos, end); } @@ -2556,7 +2438,7 @@ ngx_http_v2_send_settings(ngx_http_v2_co buf->last = ngx_http_v2_write_uint16(buf->last, NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING); buf->last = ngx_http_v2_write_uint32(buf->last, - NGX_HTTP_V2_MAX_WINDOW); + NGX_HTTP_V2_INITIAL_WINDOW); buf->last = ngx_http_v2_write_uint16(buf->last, NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING); @@ -2867,7 +2749,7 @@ ngx_http_v2_create_stream(ngx_http_v2_co stream->connection = h2c; stream->send_window = h2c->init_window; - stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + stream->recv_window = NGX_HTTP_V2_INITIAL_WINDOW; h2c->processing++; @@ -3504,7 +3386,7 @@ ngx_http_v2_run_request(ngx_http_request ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client prematurely closed stream"); - r->stream->skip_data = NGX_HTTP_V2_DATA_ERROR; + r->stream->skip_data = 1; ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; @@ -3514,142 +3396,241 @@ ngx_http_v2_run_request(ngx_http_request } -static ngx_int_t -ngx_http_v2_init_request_body(ngx_http_request_t *r) -{ - ngx_buf_t *buf; - ngx_temp_file_t *tf; - ngx_http_request_body_t *rb; - ngx_http_core_loc_conf_t *clcf; - - rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); - if (rb == NULL) { - return NGX_ERROR; - } - - r->request_body = rb; - - if (r->stream->in_closed) { - return NGX_OK; - } - - rb->rest = r->headers_in.content_length_n; - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (r->request_body_in_file_only - || rb->rest > (off_t) clcf->client_body_buffer_size - || rb->rest < 0) - { - tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); - if (tf == NULL) { - return NGX_ERROR; - } - - tf->file.fd = NGX_INVALID_FILE; - tf->file.log = r->connection->log; - tf->path = clcf->client_body_temp_path; - tf->pool = r->pool; - tf->warn = "a client request body is buffered to a temporary file"; - tf->log_level = r->request_body_file_log_level; - tf->persistent = r->request_body_in_persistent_file; - tf->clean = r->request_body_in_clean_file; - - if (r->request_body_file_group_access) { - tf->access = 0660; - } - - rb->temp_file = tf; - - if (r->stream->in_closed - && ngx_create_temp_file(&tf->file, tf->path, tf->pool, - tf->persistent, tf->clean, tf->access) - != NGX_OK) - { - return NGX_ERROR; - } - - buf = ngx_calloc_buf(r->pool); - if (buf == NULL) { - return NGX_ERROR; - } - - } else { - - if (rb->rest == 0) { - return NGX_OK; - } - - buf = ngx_create_temp_buf(r->pool, (size_t) rb->rest); - if (buf == NULL) { - return NGX_ERROR; - } - } - - rb->buf = buf; - - rb->bufs = ngx_alloc_chain_link(r->pool); - if (rb->bufs == NULL) { - return NGX_ERROR; - } - - rb->bufs->buf = buf; - rb->bufs->next = NULL; - - rb->rest = 0; - - return NGX_OK; -} - - ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r, ngx_http_client_body_handler_pt post_handler) { + off_t len; ngx_http_v2_stream_t *stream; + ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http2 read request body"); - stream = r->stream; - switch (stream->skip_data) { - - case NGX_HTTP_V2_DATA_DISCARD: - post_handler(r); + rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); + if (rb == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + /* + * set by ngx_pcalloc(): + * + * rb->bufs = NULL; + * rb->buf = NULL; + * rb->received = 0; + * rb->free = NULL; + * rb->busy = NULL; + */ + + rb->post_handler = post_handler; + + r->request_body = rb; + + if (stream->skip_data) { + return NGX_HTTP_BAD_REQUEST; + } + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + len = r->headers_in.content_length_n; + + if (stream->in_closed && len < 0) { + len = 0; + } + + if (len != 0) { + if (len < 0 + || len > (off_t) clcf->client_body_buffer_size + || r->request_body_in_file_only) + { + rb->buf = ngx_calloc_buf(r->pool); + + if (rb->buf != NULL) { + rb->buf->memory = 1; + rb->buf->sync = 1; + } + + } else { + rb->buf = ngx_create_temp_buf(r->pool, (size_t) len); + } + + if (rb->buf == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + } + + if (stream->in_closed) { + return ngx_http_v2_process_request_body(r, NULL, 0, 1); + } + + stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + + if (ngx_http_v2_send_window_update(stream->connection, stream->node->id, + stream->recv_window) + == NGX_ERROR) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + stream->no_flow_control = 1; + + ngx_add_timer(r->connection->read, clcf->client_body_timeout); + + r->read_event_handler = ngx_http_v2_read_client_request_body_handler; + r->write_event_handler = ngx_http_request_empty_handler; + + return NGX_AGAIN; +} + + +static ngx_int_t +ngx_http_v2_account_request_body(ngx_http_request_t *r, size_t size, + ngx_uint_t last) +{ + ngx_http_request_body_t *rb; + ngx_http_core_loc_conf_t *clcf; + + rb = r->request_body; + + if (rb == NULL) { return NGX_OK; - - case NGX_HTTP_V2_DATA_ERROR: - if (r->headers_in.content_length_n == -1) { - return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; - } else { + } + + if (size) { + r->request_length += size; + rb->received += size; + + if (r->headers_in.content_length_n != -1 + && r->headers_in.content_length_n < rb->received) + { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client intended to send body data " + "larger than declared"); + return NGX_HTTP_BAD_REQUEST; } - case NGX_HTTP_V2_DATA_INTERNAL_ERROR: - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (!r->request_body && ngx_http_v2_init_request_body(r) != NGX_OK) { - stream->skip_data = NGX_HTTP_V2_DATA_INTERNAL_ERROR; - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (stream->in_closed) { - post_handler(r); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->client_max_body_size + && clcf->client_max_body_size < rb->received) + { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "client intended to send too large chunked body: " + "%O bytes", rb->received); + + return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; + } + } + + if (last) { + if (r->headers_in.content_length_n != -1 + && r->headers_in.content_length_n != rb->received) + { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client prematurely closed stream: " + "only %O out of %O bytes of request body received", + rb->received, r->headers_in.content_length_n); + + return NGX_HTTP_BAD_REQUEST; + } + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_v2_process_request_body(ngx_http_request_t *r, u_char *pos, + size_t size, ngx_uint_t last) +{ + ngx_buf_t *buf; + ngx_int_t rc; + ngx_chain_t out; + ngx_connection_t *fc; + 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; } - r->request_body->post_handler = post_handler; - - r->read_event_handler = ngx_http_v2_read_client_request_body_handler; - r->write_event_handler = ngx_http_request_empty_handler; + rb->rest = !last; + + buf = rb->buf; + + if (size) { + if (buf->sync) { + buf->start = pos; + buf->pos = pos; + + pos += size; + + buf->end = pos; + buf->last = pos; + + buf->last_buf = last; + + out.buf = buf; + out.next = NULL; + + rc = ngx_http_top_request_body_filter(r, &out); + + if (rc != NGX_OK) { + return rc; + } + + } else { + buf->last = ngx_cpymem(buf->last, pos, size); + } + } + + if (last) { + if (r->headers_in.content_length_n < 0) { + r->headers_in.content_length_n = rb->received; + } + + if (buf) { + if (buf->sync) { + /* prevent reusing this buffer in the upstream module */ + rb->buf = NULL; + + rc = size ? NGX_OK : ngx_http_top_request_body_filter(r, NULL); + + } else { + buf->last_buf = 1; + + out.buf = buf; + out.next = NULL; + + rc = ngx_http_top_request_body_filter(r, &out); + } + + } else { + rc = ngx_http_top_request_body_filter(r, NULL); + } + + if (rc != NGX_OK) { + return rc; + } + + if (fc->read->timer_set) { + ngx_del_timer(fc->read); + } + + r->read_event_handler = ngx_http_block_reading; + rb->post_handler(r); + + return NGX_OK; + } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_add_timer(r->connection->read, clcf->client_body_timeout); - - return NGX_AGAIN; + ngx_add_timer(fc->read, clcf->client_body_timeout); + + return NGX_OK; } @@ -3667,7 +3648,7 @@ ngx_http_v2_read_client_request_body_han ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out"); fc->timedout = 1; - r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD; + r->stream->skip_data = 1; ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); return; @@ -3677,7 +3658,7 @@ ngx_http_v2_read_client_request_body_han ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client prematurely closed stream"); - r->stream->skip_data = NGX_HTTP_V2_DATA_DISCARD; + r->stream->skip_data = 1; ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST); return; diff -r 1f4781e6b904 -r edacc9766e8e src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Fri Feb 26 14:39:50 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Fri Feb 26 18:02:02 2016 +0300 @@ -194,7 +194,8 @@ struct ngx_http_v2_stream_s { unsigned exhausted:1; unsigned in_closed:1; unsigned out_closed:1; - unsigned skip_data:2; + unsigned no_flow_control:1; + unsigned skip_data:1; }; From vbart at nginx.com Fri Feb 26 15:45:58 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Fri, 26 Feb 2016 18:45:58 +0300 Subject: [PATCH 3 of 4] HTTP/2: improved debugging of sending control frames In-Reply-To: References: Message-ID: <8933cfd2fb603a65f5ed.1456501558@localhost> src/http/v2/ngx_http_v2.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) # HG changeset patch # User Valentin Bartenev # Date 1456500146 -10800 # Fri Feb 26 18:22:26 2016 +0300 # Node ID 8933cfd2fb603a65f5ed8b49922abc9b03840375 # Parent edacc9766e8e7f610921f71739e6797f771cf2b6 HTTP/2: improved debugging of sending control frames. diff -r edacc9766e8e -r 8933cfd2fb60 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Feb 26 18:02:02 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Feb 26 18:22:26 2016 +0300 @@ -2385,8 +2385,8 @@ ngx_http_v2_send_settings(ngx_http_v2_co ngx_http_v2_srv_conf_t *h2scf; ngx_http_v2_out_frame_t *frame; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 send SETTINGS frame"); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 send SETTINGS frame ack:%ui", ack); frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t)); if (frame == NULL) { @@ -2477,6 +2477,10 @@ ngx_http_v2_send_window_update(ngx_http_ ngx_buf_t *buf; ngx_http_v2_out_frame_t *frame; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 send WINDOW_UPDATE frame sid:%ui, window:%uz", + sid, window); + frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_WINDOW_UPDATE_SIZE, NGX_HTTP_V2_WINDOW_UPDATE_FRAME, NGX_HTTP_V2_NO_FLAG, sid); @@ -2501,6 +2505,10 @@ ngx_http_v2_send_rst_stream(ngx_http_v2_ ngx_buf_t *buf; 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", + sid, status); + frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_RST_STREAM_SIZE, NGX_HTTP_V2_RST_STREAM_FRAME, NGX_HTTP_V2_NO_FLAG, sid); @@ -2524,6 +2532,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); + frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_GOAWAY_SIZE, NGX_HTTP_V2_GOAWAY_FRAME, NGX_HTTP_V2_NO_FLAG, 0); From vbart at nginx.com Fri Feb 26 15:45:59 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Fri, 26 Feb 2016 18:45:59 +0300 Subject: [PATCH 4 of 4] HTTP/2: support for unbuffered upload of request body In-Reply-To: References: Message-ID: src/http/ngx_http_request_body.c | 7 +- src/http/v2/ngx_http_v2.c | 132 +++++++++++++++++++++++++++++++++++++- src/http/v2/ngx_http_v2.h | 1 + 3 files changed, 134 insertions(+), 6 deletions(-) # HG changeset patch # User Valentin Bartenev # Date 1456500171 -10800 # Fri Feb 26 18:22:51 2016 +0300 # Node ID d0745c528544d1297ba11cc8d3660929a2bce557 # Parent 8933cfd2fb603a65f5ed8b49922abc9b03840375 HTTP/2: support for unbuffered upload of request body. diff -r 8933cfd2fb60 -r d0745c528544 src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c Fri Feb 26 18:22:26 2016 +0300 +++ b/src/http/ngx_http_request_body.c Fri Feb 26 18:22:51 2016 +0300 @@ -48,7 +48,6 @@ ngx_http_read_client_request_body(ngx_ht #if (NGX_HTTP_V2) if (r->stream) { - r->request_body_no_buffering = 0; rc = ngx_http_v2_read_request_body(r, post_handler); goto done; } @@ -215,6 +214,12 @@ ngx_http_read_unbuffered_request_body(ng { ngx_int_t rc; +#if (NGX_HTTP_V2) + if (r->stream) { + return ngx_http_v2_read_unbuffered_request_body(r); + } +#endif + if (r->connection->read->timedout) { r->connection->timedout = 1; return NGX_HTTP_REQUEST_TIME_OUT; diff -r 8933cfd2fb60 -r d0745c528544 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Fri Feb 26 18:22:26 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri Feb 26 18:22:51 2016 +0300 @@ -3403,6 +3403,8 @@ ngx_http_v2_run_request(ngx_http_request return; } + r->headers_in.chunked = (r->headers_in.content_length_n == -1); + ngx_http_process_request(r); } @@ -3449,6 +3451,14 @@ ngx_http_v2_read_request_body(ngx_http_r len = 0; } + if (r->request_body_no_buffering) { + r->request_body_in_file_only = 0; + + if (len < 0 || len > (off_t) clcf->client_body_buffer_size) { + len = clcf->client_body_buffer_size; + } + } + if (len != 0) { if (len < 0 || len > (off_t) clcf->client_body_buffer_size @@ -3471,10 +3481,15 @@ ngx_http_v2_read_request_body(ngx_http_r } if (stream->in_closed) { + r->request_body_no_buffering = 0; return ngx_http_v2_process_request_body(r, NULL, 0, 1); } - stream->recv_window = NGX_HTTP_V2_MAX_WINDOW; + rb->rest = 1; + + stream->recv_window = r->request_body_no_buffering + ? clcf->client_body_buffer_size + : NGX_HTTP_V2_MAX_WINDOW; if (ngx_http_v2_send_window_update(stream->connection, stream->node->id, stream->recv_window) @@ -3483,7 +3498,7 @@ ngx_http_v2_read_request_body(ngx_http_r return NGX_HTTP_INTERNAL_SERVER_ERROR; } - stream->no_flow_control = 1; + stream->no_flow_control = !r->request_body_no_buffering; ngx_add_timer(r->connection->read, clcf->client_body_timeout); @@ -3557,7 +3572,7 @@ ngx_http_v2_process_request_body(ngx_htt { ngx_buf_t *buf; ngx_int_t rc; - ngx_chain_t out; + ngx_chain_t out, *cl; ngx_connection_t *fc; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; @@ -3596,6 +3611,32 @@ ngx_http_v2_process_request_body(ngx_htt } else { buf->last = ngx_cpymem(buf->last, pos, size); + + if (r->request_body_no_buffering && !last) { + cl = ngx_chain_get_free_buf(r->pool, &rb->free); + if (cl == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ngx_memcpy(cl->buf, buf, sizeof(ngx_buf_t)); + + cl->buf->flush = 1; + cl->buf->tag = + (ngx_buf_tag_t) &ngx_http_v2_process_request_body; + + rc = ngx_http_top_request_body_filter(r, cl); + + ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &cl, + (ngx_buf_tag_t) &ngx_http_v2_process_request_body); + + if (rc != NGX_OK) { + return rc; + } + + buf->pos = buf->last; + + ngx_post_event(fc->read, &ngx_posted_events); + } } } @@ -3632,8 +3673,13 @@ ngx_http_v2_process_request_body(ngx_htt ngx_del_timer(fc->read); } - r->read_event_handler = ngx_http_block_reading; - rb->post_handler(r); + if (r->request_body_no_buffering) { + r->read_event_handler(r); + + } else { + r->read_event_handler = ngx_http_block_reading; + rb->post_handler(r); + } return NGX_OK; } @@ -3677,6 +3723,82 @@ ngx_http_v2_read_client_request_body_han } +ngx_int_t +ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r) +{ + size_t available; + ngx_buf_t *buf; + ngx_connection_t *fc; + ngx_http_v2_stream_t *stream; + ngx_http_v2_connection_t *h2c; + ngx_http_core_loc_conf_t *clcf; + + stream = r->stream; + fc = r->connection; + + if (fc->read->timedout) { + if (stream->recv_window == 0) { + return NGX_AGAIN; + } + + stream->skip_data = 1; + fc->timedout = 1; + + return NGX_HTTP_REQUEST_TIME_OUT; + } + + if (fc->error) { + stream->skip_data = 1; + return NGX_ERROR; + } + + if (!r->request_body->rest) { + r->reading_body = 0; + return NGX_OK; + } + + buf = r->request_body->buf; + + if (buf->pos != buf->last) { + return NGX_AGAIN; + } + + buf->pos = buf->start; + buf->last = buf->start; + + available = buf->end - buf->start; + + h2c = stream->connection; + + if (h2c->state.stream == stream) { + available -= h2c->state.length; + } + + if (available > stream->recv_window && !stream->in_closed) { + + if (ngx_http_v2_send_window_update(h2c, stream->node->id, + available - stream->recv_window) + == NGX_ERROR) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (stream->recv_window == 0) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ngx_add_timer(fc->read, clcf->client_body_timeout); + } + + stream->recv_window = available; + + if (!h2c->blocked && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + } + + return NGX_AGAIN; +} + + static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream, ngx_uint_t status) diff -r 8933cfd2fb60 -r d0745c528544 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Fri Feb 26 18:22:26 2016 +0300 +++ b/src/http/v2/ngx_http_v2.h Fri Feb 26 18:22:51 2016 +0300 @@ -263,6 +263,7 @@ void ngx_http_v2_request_headers_init(vo ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r, ngx_http_client_body_handler_pt post_handler); +ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r); void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc); From ru at nginx.com Mon Feb 29 15:52:54 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 29 Feb 2016 15:52:54 +0000 Subject: [nginx] Dynamic modules: expose the "modules" target. Message-ID: details: http://hg.nginx.org/nginx/rev/8e6f34342eb6 branches: changeset: 6418:8e6f34342eb6 user: Ruslan Ermilov date: Mon Feb 29 18:52:33 2016 +0300 description: Dynamic modules: expose the "modules" target. diffstat: auto/install | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r ce946e0976dc -r 8e6f34342eb6 auto/install --- a/auto/install Thu Feb 25 16:29:51 2016 +0300 +++ b/auto/install Mon Feb 29 18:52:33 2016 +0300 @@ -190,6 +190,9 @@ build: install: \$(MAKE) -f $NGX_MAKEFILE install +modules: + \$(MAKE) -f $NGX_MAKEFILE modules + upgrade: $NGX_SBIN_PATH -t From coreykasten at gmail.com Mon Feb 29 18:57:49 2016 From: coreykasten at gmail.com (Corey Kasten) Date: Mon, 29 Feb 2016 10:57:49 -0800 Subject: [PATCH] Skip writing pidfile when old and new paths are equivalent Message-ID: # HG changeset patch # User Corey Kasten # Date 1456771518 28800 # Mon Feb 29 10:45:18 2016 -0800 # Node ID a2365d15b75c9537efacbef038a67dde693a7f0f # Parent 8e6f34342eb652046fdfcd0d0677f0d20483c0a5 Skip writing pidfile when old and new paths are equivalent On an nginx reload, if the pidfile path has changed, the pid is written to the new path, and the old file is deleted. This behaviour is problematic when the old path (e.g. /run/nginx.pid) is equivalent to the new path (e.g. /var/run/nginx.pid), due to the use of a symbolic link (/var/run -> /run). After deleting the file at the old path, we are left without a .pid file, since the new and old were actually the same file. The solution employed here is to check whether the two paths resolve to the same inode via stat(2). diff -r 8e6f34342eb6 -r a2365d15b75c src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c Mon Feb 29 18:52:33 2016 +0300 +++ b/src/core/ngx_cycle.c Mon Feb 29 10:45:18 2016 -0800 @@ -15,6 +15,7 @@ ngx_shm_zone_t *shm_zone); static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log); static void ngx_clean_old_cycles(ngx_event_t *ev); +static int are_same_file(u_char *file1, u_char *file2); volatile ngx_cycle_t *ngx_cycle; @@ -322,8 +323,9 @@ old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx, ngx_core_module); - if (ccf->pid.len != old_ccf->pid.len + if ((ccf->pid.len != old_ccf->pid.len || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0) + && !are_same_file(ccf->pid.data, old_ccf->pid.data)) { /* new pid file name */ @@ -1337,3 +1339,32 @@ ngx_old_cycles.nelts = 0; } } + +static int +are_same_file(u_char *file1, u_char *file2) +{ +#if !(NGX_WIN32) + ngx_file_info_t fi1, fi2; + + if (ngx_file_info((const char *) file1, &fi1) == NGX_FILE_ERROR) + { + return 0; + } + + if (ngx_file_info((const char *) file2, &fi2) == NGX_FILE_ERROR) + { + return 0; + } + + if (fi1.st_ino != fi2.st_ino || + major(fi1.st_dev) != major(fi2.st_dev) || + minor(fi1.st_dev) != minor(fi2.st_dev)) + { + return 0; + } + + return 1; +#else + return 0; +#endif +} From ru at nginx.com Mon Feb 29 20:22:51 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 29 Feb 2016 20:22:51 +0000 Subject: [nginx] Dynamic modules: perl. Message-ID: details: http://hg.nginx.org/nginx/rev/39a806ccf21e branches: changeset: 6419:39a806ccf21e user: Ruslan Ermilov date: Fri Feb 26 14:27:04 2016 +0300 description: Dynamic modules: perl. diffstat: auto/install | 2 +- auto/lib/conf | 2 +- auto/lib/make | 2 +- auto/lib/perl/conf | 7 +++++-- auto/lib/perl/make | 5 ++++- auto/make | 29 +++++++++++++++++++++-------- auto/module | 4 ++-- auto/modules | 6 ++---- auto/options | 2 ++ 9 files changed, 39 insertions(+), 20 deletions(-) diffs (197 lines): diff -r 8e6f34342eb6 -r 39a806ccf21e auto/install --- a/auto/install Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/install Fri Feb 26 14:27:04 2016 +0300 @@ -3,7 +3,7 @@ # Copyright (C) Nginx, Inc. -if [ $USE_PERL = YES ]; then +if [ $USE_PERL != NO ]; then cat << END >> $NGX_MAKEFILE diff -r 8e6f34342eb6 -r 39a806ccf21e auto/lib/conf --- a/auto/lib/conf Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/lib/conf Fri Feb 26 14:27:04 2016 +0300 @@ -66,7 +66,7 @@ if [ $USE_LIBGD != NO ]; then . auto/lib/libgd/conf fi -if [ $USE_PERL = YES ]; then +if [ $USE_PERL != NO ]; then . auto/lib/perl/conf fi diff -r 8e6f34342eb6 -r 39a806ccf21e auto/lib/make --- a/auto/lib/make Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/lib/make Fri Feb 26 14:27:04 2016 +0300 @@ -27,6 +27,6 @@ if [ $NGX_LIBATOMIC != NO -a $NGX_LIBATO . auto/lib/libatomic/make fi -if [ $USE_PERL = YES ]; then +if [ $USE_PERL != NO ]; then . auto/lib/perl/make fi diff -r 8e6f34342eb6 -r 39a806ccf21e auto/lib/perl/conf --- a/auto/lib/perl/conf Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/lib/perl/conf Fri Feb 26 14:27:04 2016 +0300 @@ -60,8 +60,11 @@ if test -n "$NGX_PERL_VER"; then | sed -e 's/-arch i386//' -e 's/-arch x86_64//'` fi - CORE_LINK="$CORE_LINK $ngx_perl_ldopts" - LINK_DEPS="$LINK_DEPS $NGX_OBJS/$ngx_perl_module" + if [ $USE_PERL = YES ]; then + CORE_LINK="$CORE_LINK $ngx_perl_ldopts" + fi + + NGX_LIB_PERL="$ngx_perl_ldopts" if test -n "$NGX_PERL_MODULES"; then have=NGX_PERL_MODULES value="(u_char *) \"$NGX_PERL_MODULES\"" diff -r 8e6f34342eb6 -r 39a806ccf21e auto/lib/perl/make --- a/auto/lib/perl/make Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/lib/perl/make Fri Feb 26 14:27:04 2016 +0300 @@ -8,7 +8,10 @@ v=`grep 'define NGINX_VERSION' src/core/ cat << END >> $NGX_MAKEFILE -$NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext: \\ +$NGX_OBJS/src/http/modules/perl/ngx_http_perl_module.o: \\ + $NGX_OBJS/$ngx_perl_module + +$NGX_OBJS/$ngx_perl_module: \\ \$(CORE_DEPS) \$(HTTP_DEPS) \\ src/http/modules/perl/ngx_http_perl_module.h \\ $NGX_OBJS/src/http/modules/perl/Makefile diff -r 8e6f34342eb6 -r 39a806ccf21e auto/make --- a/auto/make Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/make Fri Feb 26 14:27:04 2016 +0300 @@ -281,7 +281,7 @@ if [ $HTTP = YES ]; then ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" else ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)" - ngx_perl_cc="\$(CC) $ngx_compile_opt \$(NGX_PERL_CFLAGS) " + ngx_perl_cc="\$(CC) $ngx_compile_opt \$(NGX_PERL_CFLAGS)" ngx_perl_cc="$ngx_perl_cc \$(CORE_INCS) \$(HTTP_INCS)" fi @@ -494,6 +494,8 @@ if test -n "$NGX_PCH"; then ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" else ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) \$(ALL_INCS)" + ngx_perl_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(NGX_PERL_CFLAGS)" + ngx_perl_cc="$ngx_perl_cc \$(ALL_INCS)" fi ngx_obj_deps="\$(CORE_DEPS)" @@ -639,15 +641,15 @@ modules: $ngx_obj END - for ngx_src in $ngx_module_srcs + for ngx_source in $ngx_module_srcs do - case "$ngx_src" in + case "$ngx_source" in src/*) - ngx_obj=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` + ngx_obj=`echo $ngx_source | sed -e "s/\//$ngx_regex_dirsep/g"` ;; *) - ngx_obj="addon/`basename \`dirname $ngx_src\``" - ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \ + ngx_obj="addon/`basename \`dirname $ngx_source\``" + ngx_obj=`echo $ngx_obj/\`basename $ngx_source\` \ | sed -e "s/\//$ngx_regex_dirsep/g"` ;; esac @@ -658,14 +660,25 @@ END -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \ -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"` - ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` + ngx_src=`echo $ngx_source | sed -e "s/\//$ngx_regex_dirsep/g"` - cat << END >> $NGX_MAKEFILE + if [ $ngx_source = src/http/modules/perl/ngx_http_perl_module.c ]; then + + cat << END >> $NGX_MAKEFILE + +$ngx_obj: $ngx_obj_deps$ngx_cont$ngx_src + $ngx_perl_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX + +END + else + + cat << END >> $NGX_MAKEFILE $ngx_obj: $ngx_obj_deps$ngx_cont$ngx_src $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX END + fi done done diff -r 8e6f34342eb6 -r 39a806ccf21e auto/module --- a/auto/module Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/module Fri Feb 26 14:27:04 2016 +0300 @@ -40,7 +40,7 @@ if [ "$ngx_module_link" = DYNAMIC ]; the do case $lib in - LIBXSLT | LIBGD | GEOIP) + LIBXSLT | LIBGD | GEOIP | PERL) libs="$libs \$NGX_LIB_$lib" if eval [ "\$USE_${lib}" = NO ] ; then @@ -48,7 +48,7 @@ if [ "$ngx_module_link" = DYNAMIC ]; the fi ;; - PCRE | OPENSSL | MD5 | SHA1 | ZLIB | PERL) + PCRE | OPENSSL | MD5 | SHA1 | ZLIB) eval USE_${lib}=YES ;; diff -r 8e6f34342eb6 -r 39a806ccf21e auto/modules --- a/auto/modules Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/modules Fri Feb 26 14:27:04 2016 +0300 @@ -727,14 +727,12 @@ if [ $HTTP_SCGI = YES ]; then . auto/module fi -if [ $HTTP_PERL = YES ]; then - USE_PERL=YES - +if [ $HTTP_PERL != NO ]; then ngx_module_name=ngx_http_perl_module ngx_module_incs=src/http/modules/perl ngx_module_deps=src/http/modules/perl/ngx_http_perl_module.h ngx_module_srcs=src/http/modules/perl/ngx_http_perl_module.c - ngx_module_libs= + ngx_module_libs=PERL ngx_module_link=$HTTP_PERL . auto/module diff -r 8e6f34342eb6 -r 39a806ccf21e auto/options --- a/auto/options Mon Feb 29 18:52:33 2016 +0300 +++ b/auto/options Fri Feb 26 14:27:04 2016 +0300 @@ -271,6 +271,7 @@ do --without-http_upstream_zone_module) HTTP_UPSTREAM_ZONE=NO ;; --with-http_perl_module) HTTP_PERL=YES ;; + --with-http_perl_module=dynamic) HTTP_PERL=DYNAMIC ;; --with-perl_modules_path=*) NGX_PERL_MODULES="$value" ;; --with-perl=*) NGX_PERL="$value" ;; @@ -452,6 +453,7 @@ cat << END disable ngx_http_upstream_zone_module --with-http_perl_module enable ngx_http_perl_module + --with-http_perl_module=dynamic enable dynamic ngx_http_perl_module --with-perl_modules_path=PATH set Perl modules path --with-perl=PATH set perl binary pathname