From 0 at lvht.net Mon May 1 00:31:01 2017 From: 0 at lvht.net (=?utf-8?B?5ZCV5rW35rab?=) Date: Mon, 1 May 2017 08:31:01 +0800 Subject: Http: make ngx_http_init_listening a public api Message-ID: # HG changeset patch # User ??? <0 at lvht.net> # Date 1493595577 -28800 # Mon May 01 07:39:37 2017 +0800 # Node ID 2ddd0894c1a6c7efe45310b874a5b4091b58bb81 # Parent f38647c651a8d5c884b5aacc9f9a5b1af196309b Http: make ngx_http_init_listening a public api Make this api public is a good convenience to allow other module add listening port to http server dynamically. diff -r f38647c651a8 -r 2ddd0894c1a6 src/http/ngx_http.c --- a/src/http/ngx_http.c Thu Apr 27 16:57:18 2017 +0300 +++ b/src/http/ngx_http.c Mon May 01 07:39:37 2017 +0800 @@ -55,8 +55,6 @@ static ngx_int_t ngx_http_cmp_conf_addrs static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one, const void *two); -static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, - ngx_http_conf_port_t *port); static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr); static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport, @@ -1623,7 +1621,7 @@ ngx_http_cmp_dns_wildcards(const void *o } -static ngx_int_t +ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port) { ngx_uint_t i, last, bind_wildcard; diff -r f38647c651a8 -r 2ddd0894c1a6 src/http/ngx_http.h --- a/src/http/ngx_http.h Thu Apr 27 16:57:18 2017 +0300 +++ b/src/http/ngx_http.h Mon May 01 07:39:37 2017 +0800 @@ -80,6 +80,7 @@ ngx_int_t ngx_http_add_location(ngx_conf ngx_http_core_loc_conf_t *clcf); ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, ngx_http_listen_opt_t *lsopt); +ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port); void ngx_http_init_connection(ngx_connection_t *c); From piotrsikora at google.com Mon May 1 04:37:36 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Sun, 30 Apr 2017 21:37:36 -0700 Subject: [PATCH 1 of 3] HTTP: add support for trailers in HTTP responses In-Reply-To: <20170427184623.GD43932@mdounin.ru> References: <8af81a0d66c0f69bcf50.1491211931@piotrsikora.sfo.corp.google.com> <20170421174201.GA43932@mdounin.ru> <20170427184623.GD43932@mdounin.ru> Message-ID: Hey Maxim, > As you can see from the quote, it talks about not generating > "trailer fields that it believes are necessary for the user agent > to receive". RFC 2616 is even more clear on this, specifically > lists two cases when trailers can be generated, section 3.6.1: > > A server using chunked transfer-coding in a response MUST NOT use the > trailer for any header fields unless at least one of the following is > true: > > a)the request included a TE header field that indicates "trailers" is > acceptable in the transfer-coding of the response, as described in > section 14.39; or, > > b)the server is the origin server for the response, the trailer > fields consist entirely of optional metadata, and the recipient > could use the message (in a manner acceptable to the origin server) > without receiving this metadata. In other words, the origin server > is willing to accept the possibility that the trailer fields might > be silently discarded along the path to the client. > > That is, there clearly two cases when a server can / should send > trailers: > > - when there is "TE: trailers"; > > - when trailers are optional. > > Moreover, given that "TE: trailers" does _not_ guarantee anything > either (see link above), the only remaining case seems to be "when > trailers are optional". I disagree, if someone adds trailers in their configuration, then they are hardly optional, therefore they should be sent in response to requests with "TE: trailers". > As per previous discussion, main cases, as listed by you, are: > > 1. Checksums, like Content-SHA256. > 2. Logging, like X-Log-Something for centralized logging on a > frontend. > 3. Trailing status, like X-Status, to provide additional error > information to a frontend. > > All these uses cases hardly require "TE: trailers", as in all > cases information seems optional. Moreover, in cases (2) and (3), > backend cannot have "TE: trailers" unless it was already present > in the original request from the client. Adding such a header > would contradict RFC 7230, which says: > > The presence of the keyword "trailers" indicates that the client is > willing to accept trailer fields in a chunked transfer coding, as > defined in Section 4.1.2, on behalf of itself and any downstream > clients. For requests from an intermediary, this implies that > either: (a) all downstream clients are willing to accept trailer > fields in the forwarded response; or, (b) the intermediary will > attempt to buffer the response on behalf of downstream recipients. > > So both cases (2) and (3) generally require that "TE: trailers" > should be ignored, or it won't be possible to implement them. That's valid argument. > Current nginx behaviour is to don't emit trailers by default, and > I don't think we anyhow change this beaviour unless explicitly > requested via appropriate configuration directives. This looks > conservative enough for me, actually. Yes, of course. What I meant is that if some module produces trailers and it's enabled in the configuration, then even if there are only few obscure clients that break because of it, the only option will be to disable them altogether, instead of only sending them in response to requests with "TE: trailers". Anyway, I'll just remove that requirement for now, and you can re-add it later if/when others complain. > I can see that r->expect_trailers can be useful to indicate that > the code wants to use trailers, and would like to force chunked > encoding if possible. > > I don't see why it should be required when encoding is already > choosen though. If we know that we can use trailers or don't > care, we can just add trailers to the response, and assume they > will be sent if it is possible to do so. I'm confused, it sounds like you're saying two opposite things... Are you saying that r->expect_trailers should be removed and we should send trailers only if transfer encoding is already chunked and not send trailers otherwise? > As per HTTP specification, trailers are expected to be sent as > normal headers when there is no body, for both HTTP/1.1 and > HTTP/2. And I suspect that the fact that HTTP/2 allows two > HEADERS frames without body inbetween is more or less > unintentional, too. > > (...) > > I certainly against intruduction of such a difference between > HTTP/1.1 and HTTP/2 behaviour. So what do you suggest we do instead? Merge them with headers? Wasn't that your biggest concern from the beginning? Also, how would you merge them in upstream? Cacheable responses to HEAD requests are "terminated" and headers are sent before upstream sends complete response, so trailers would be dropped there (at least in the existing code). Best regards, Piotr Sikora From matwey.kornilov at gmail.com Mon May 1 10:09:57 2017 From: matwey.kornilov at gmail.com (Matwey V. Kornilov) Date: Mon, 01 May 2017 13:09:57 +0300 Subject: [PATCH 2 of 2] SSI: implemented "flastmod" SSI command In-Reply-To: <0d6c509169a32624cce4.1493633396@oak.local> References: <0d6c509169a32624cce4.1493633396@oak.local> Message-ID: <585e9fd5aecdc3e7ea7c.1493633397@oak.local> # HG changeset patch # User Matwey V. Kornilov # Date 1493632942 -10800 # Mon May 01 13:02:22 2017 +0300 # Branch fsize # Node ID 585e9fd5aecdc3e7ea7c484989f837b0cfde627d # Parent 0d6c509169a32624cce431f2469b10b4f961510e SSI: implemented "flastmod" SSI command. diff -r 0d6c509169a3 -r 585e9fd5aecd src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Sun Apr 23 11:38:23 2017 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Mon May 01 13:02:22 2017 +0300 @@ -93,6 +93,8 @@ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); static ngx_int_t ngx_http_ssi_fsize_output(ngx_http_request_t *r, void *data, ngx_int_t rc); +static ngx_int_t ngx_http_ssi_flastmod_output(ngx_http_request_t *r, + void *data, ngx_int_t rc); static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); static ngx_int_t ngx_http_ssi_config(ngx_http_request_t *r, @@ -308,6 +310,8 @@ ngx_http_ssi_include_params, 0, 0, 1 }, { ngx_string("fsize"), ngx_http_ssi_fsize, ngx_http_ssi_fsize_params, 0, 0, 1 }, + { ngx_string("flastmod"), ngx_http_ssi_fsize, + ngx_http_ssi_fsize_params, 0, 0, 1 }, { ngx_string("echo"), ngx_http_ssi_echo, ngx_http_ssi_echo_params, 0, 0, 0 }, { ngx_string("config"), ngx_http_ssi_config, @@ -2273,14 +2277,14 @@ if (uri && file) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "fsize may be either virtual=\"%V\" or file=\"%V\"", - uri, file); + "%V may be either virtual=\"%V\" or file=\"%V\"", + ctx->command, uri, file); return NGX_HTTP_SSI_ERROR; } if (uri == NULL && file == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "no parameter in \"fsize\" SSI command"); + "no parameter in \"%V\" SSI command", ctx->command); return NGX_HTTP_SSI_ERROR; } @@ -2309,7 +2313,13 @@ return NGX_ERROR; } - psr->handler = ngx_http_ssi_fsize_output; + if (ctx->command.len == sizeof("fsize") - 1) { + psr->handler = ngx_http_ssi_fsize_output; + + } else if (ctx->command.len == sizeof("flastmod") - 1) { + psr->handler = ngx_http_ssi_flastmod_output; + } + psr->data = ctx; if (ngx_http_subrequest(r, uri, &args, &sr, psr, flags) != NGX_OK) { @@ -2402,6 +2412,73 @@ static ngx_int_t +ngx_http_ssi_flastmod_output(ngx_http_request_t *r, void *data, ngx_int_t rc) +{ + size_t len; + ngx_buf_t *b; + ngx_str_t *timefmt; + struct tm tm; + ngx_chain_t *out; + ngx_http_ssi_ctx_t *ctx; + + ctx = data; + timefmt = &ctx->timefmt; + + if (r->request_output) { + return rc; + } + + if (r->headers_out.last_modified_time == -1) { + b = ngx_calloc_buf(r->pool); + if (b == NULL) { + return NGX_ERROR; + } + + b->pos = ctx->errmsg.data; + b->last = ctx->errmsg.data + ctx->errmsg.len; + + } else if (timefmt->len == sizeof("%s") - 1 + && timefmt->data[0] == '%' && timefmt->data[1] == 's') + { + b = ngx_create_temp_buf(r->pool, NGX_TIME_T_LEN); + if (b == NULL) { + return NGX_ERROR; + } + + b->last = ngx_sprintf(b->last, "%T", r->headers_out.last_modified_time); + + } else { + b = ngx_create_temp_buf(r->pool, NGX_HTTP_SSI_DATE_LEN); + if (b == NULL) { + return NGX_ERROR; + } + + ngx_libc_localtime(r->headers_out.last_modified_time, &tm); + + len = strftime((char *)b->last, NGX_HTTP_SSI_DATE_LEN, + (char *) timefmt->data, &tm); + if (len == 0) { + b->pos = ctx->errmsg.data; + b->last = ctx->errmsg.data + ctx->errmsg.len; + + } else { + b->last = b->last + len; + } + } + + out = ngx_alloc_chain_link(r->pool); + if (out == NULL) { + return NGX_ERROR; + } + + out->buf = b; + out->next = NULL; + + return ngx_http_output_filter(r, out); +} + + +static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params) { From matwey.kornilov at gmail.com Mon May 1 10:09:56 2017 From: matwey.kornilov at gmail.com (Matwey V. Kornilov) Date: Mon, 01 May 2017 13:09:56 +0300 Subject: [PATCH 1 of 2] SSI: implemented "fsize" SSI command Message-ID: <0d6c509169a32624cce4.1493633396@oak.local> # HG changeset patch # User Matwey V. Kornilov # Date 1492936703 -10800 # Sun Apr 23 11:38:23 2017 +0300 # Branch fsize # Node ID 0d6c509169a32624cce431f2469b10b4f961510e # Parent 5116cfea1e9a84be678af10e0ff1f1fce9b00cfb SSI: implemented "fsize" SSI command. diff -r 5116cfea1e9a -r 0d6c509169a3 src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Thu Apr 20 18:26:38 2017 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Sun Apr 23 11:38:23 2017 +0300 @@ -89,6 +89,10 @@ ngx_int_t rc); static ngx_int_t ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data, ngx_int_t rc); +static ngx_int_t ngx_http_ssi_fsize(ngx_http_request_t *r, + ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); +static ngx_int_t ngx_http_ssi_fsize_output(ngx_http_request_t *r, void *data, + ngx_int_t rc); static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); static ngx_int_t ngx_http_ssi_config(ngx_http_request_t *r, @@ -223,12 +227,16 @@ #define NGX_HTTP_SSI_INCLUDE_SET 3 #define NGX_HTTP_SSI_INCLUDE_STUB 4 +#define NGX_HTTP_SSI_FSIZE_VIRTUAL 0 +#define NGX_HTTP_SSI_FSIZE_FILE 1 + #define NGX_HTTP_SSI_ECHO_VAR 0 #define NGX_HTTP_SSI_ECHO_DEFAULT 1 #define NGX_HTTP_SSI_ECHO_ENCODING 2 #define NGX_HTTP_SSI_CONFIG_ERRMSG 0 #define NGX_HTTP_SSI_CONFIG_TIMEFMT 1 +#define NGX_HTTP_SSI_CONFIG_SIZEFMT 2 #define NGX_HTTP_SSI_SET_VAR 0 #define NGX_HTTP_SSI_SET_VALUE 1 @@ -248,6 +256,13 @@ }; +static ngx_http_ssi_param_t ngx_http_ssi_fsize_params[] = { + { ngx_string("virtual"), NGX_HTTP_SSI_FSIZE_VIRTUAL, 0, 0 }, + { ngx_string("file"), NGX_HTTP_SSI_FSIZE_FILE, 0, 0 }, + { ngx_null_string, 0, 0, 0 } +}; + + static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = { { ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 }, { ngx_string("default"), NGX_HTTP_SSI_ECHO_DEFAULT, 0, 0 }, @@ -259,6 +274,7 @@ static ngx_http_ssi_param_t ngx_http_ssi_config_params[] = { { ngx_string("errmsg"), NGX_HTTP_SSI_CONFIG_ERRMSG, 0, 0 }, { ngx_string("timefmt"), NGX_HTTP_SSI_CONFIG_TIMEFMT, 0, 0 }, + { ngx_string("sizefmt"), NGX_HTTP_SSI_CONFIG_SIZEFMT, 0, 0 }, { ngx_null_string, 0, 0, 0 } }; @@ -290,6 +306,8 @@ static ngx_http_ssi_command_t ngx_http_ssi_commands[] = { { ngx_string("include"), ngx_http_ssi_include, ngx_http_ssi_include_params, 0, 0, 1 }, + { ngx_string("fsize"), ngx_http_ssi_fsize, + ngx_http_ssi_fsize_params, 0, 0, 1 }, { ngx_string("echo"), ngx_http_ssi_echo, ngx_http_ssi_echo_params, 0, 0, 0 }, { ngx_string("config"), ngx_http_ssi_config, @@ -2241,6 +2259,149 @@ static ngx_int_t +ngx_http_ssi_fsize(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, + ngx_str_t **params) +{ + ngx_int_t rc; + ngx_str_t *uri, *file, args; + ngx_uint_t flags; + ngx_http_request_t *sr; + ngx_http_post_subrequest_t *psr; + + uri = params[NGX_HTTP_SSI_FSIZE_VIRTUAL]; + file = params[NGX_HTTP_SSI_FSIZE_FILE]; + + if (uri && file) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "fsize may be either virtual=\"%V\" or file=\"%V\"", + uri, file); + return NGX_HTTP_SSI_ERROR; + } + + if (uri == NULL && file == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "no parameter in \"fsize\" SSI command"); + return NGX_HTTP_SSI_ERROR; + } + + if (uri == NULL) { + uri = file; + } + + rc = ngx_http_ssi_evaluate_string(r, ctx, uri, NGX_HTTP_SSI_ADD_PREFIX); + + if (rc != NGX_OK) { + return rc; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ssi fsize: \"%V\"", uri); + + ngx_str_null(&args); + flags = NGX_HTTP_LOG_UNSAFE; + + if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { + return NGX_HTTP_SSI_ERROR; + } + + psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); + if (psr == NULL) { + return NGX_ERROR; + } + + psr->handler = ngx_http_ssi_fsize_output; + psr->data = ctx; + + if (ngx_http_subrequest(r, uri, &args, &sr, psr, flags) != NGX_OK) { + return NGX_HTTP_SSI_ERROR; + } + + sr->header_only = 1; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_ssi_fsize_output(ngx_http_request_t *r, void *data, ngx_int_t rc) +{ + off_t length; + u_char scale; + unsigned exact_size; + ngx_buf_t *b; + ngx_int_t size; + ngx_chain_t *out; + ngx_http_ssi_ctx_t *ctx; + + ctx = data; + exact_size = ctx->exact_size; + + if (r->request_output) { + return rc; + } + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ssi fsize output: \"%V?%V\"", &r->uri, &r->args); + + b = ngx_create_temp_buf(r->pool, NGX_OFF_T_LEN + 2); + if (b == NULL) { + return NGX_ERROR; + } + + length = r->headers_out.content_length_n; + + if (!exact_size && length > 1024 * 1024 * 1024 - 1) { + size = (ngx_int_t) (length / (1024 * 1024 * 1024)); + if ((length % (1024 * 1024 * 1024)) + > (1024 * 1024 * 1024 / 2 - 1)) + { + size++; + } + scale = 'G'; + + } else if (!exact_size && length > 1024 * 1024 - 1) { + size = (ngx_int_t) (length / (1024 * 1024)); + if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) { + size++; + } + scale = 'M'; + + } else if (!exact_size && length > 9999) { + size = (ngx_int_t) (length / 1024); + if (length % 1024 > 511) { + size++; + } + scale = 'K'; + + } else { + size = (ngx_int_t) length; + scale = '\0'; + } + + if (length < 0) { + b->pos = ctx->errmsg.data; + b->last = ctx->errmsg.data + ctx->errmsg.len; + + } else if (scale) { + b->last = ngx_sprintf(b->last, "%6i%c", size, scale); + + } else { + b->last = ngx_sprintf(b->last, " %6i", size); + } + + out = ngx_alloc_chain_link(r->pool); + if (out == NULL) { + return NGX_ERROR; + } + + out->buf = b; + out->next = NULL; + + return ngx_http_output_filter(r, out); +} + + +static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params) { @@ -2400,6 +2561,27 @@ ctx->errmsg = *value; } + value = params[NGX_HTTP_SSI_CONFIG_SIZEFMT]; + + if (value) { + if (value->len == 5 + && ngx_strncasecmp(value->data, (u_char *) "bytes", 5) == 0) + { + ctx->exact_size = 1; + + } else if (value->len == 6 + && ngx_strncasecmp(value->data, (u_char *) "abbrev", 6) == 0) + { + ctx->exact_size = 0; + + } else { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "unknown size format \"%V\" " + "in \"config\" SSI command", value); + return NGX_HTTP_SSI_ERROR; + } + } + return NGX_OK; } diff -r 5116cfea1e9a -r 0d6c509169a3 src/http/modules/ngx_http_ssi_filter_module.h --- a/src/http/modules/ngx_http_ssi_filter_module.h Thu Apr 20 18:26:38 2017 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.h Sun Apr 23 11:38:23 2017 +0300 @@ -76,6 +76,7 @@ unsigned block:1; unsigned output:1; unsigned output_chosen:1; + unsigned exact_size:1; ngx_http_request_t *wait; void *value_buf; From astriglis at gmail.com Mon May 1 22:17:09 2017 From: astriglis at gmail.com (Aris Striglis) Date: Tue, 2 May 2017 01:17:09 +0300 Subject: Process http request before send it to the proxy Message-ID: Hello! I?m new to nginx, playing using the api and making some handlers and filters. Now what i would like to do is to process the request headers, call an external c library, do some work and pass the request to an upstream using proxy_pass. I read about http request processing phases and handler priority, but i am a little bit confused. Should i use a handler or a filter in order to work with proxy_pass? Thanks. aris -------------- next part -------------- An HTML attachment was scrubbed... URL: From hongzhidao at gmail.com Tue May 2 03:13:47 2017 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Tue, 2 May 2017 11:13:47 +0800 Subject: [nginx] Macro ngx_max/ngx_min improved Message-ID: Hi! Both 'greater' and 'less' are not the lowest priority operations, we may make a litter improvement as following. diff -r 29ba1d6a2da9 src/core/ngx_core.h --- a/src/core/ngx_core.h Tue Apr 04 18:01:57 2017 +0300 +++ b/src/core/ngx_core.h Fri Apr 28 11:27:41 2017 -0400 @@ -97,8 +97,8 @@ #define ngx_abs(value) (((value) >= 0) ? (value) : - (value)) -#define ngx_max(val1, val2) ((val1 < val2) ? (val2) : (val1)) -#define ngx_min(val1, val2) ((val1 > val2) ? (val2) : (val1)) +#define ngx_max(val1, val2) ((val1) < (val2) ? (val2) : (val1)) +#define ngx_min(val1, val2) ((val1) > (val2) ? (val2) : (val1)) void ngx_cpuinfo(void); Thanks. B.R. -------------- next part -------------- An HTML attachment was scrubbed... URL: From serg.brester at sebres.de Tue May 2 07:55:16 2017 From: serg.brester at sebres.de (Sergey Brester) Date: Tue, 02 May 2017 09:55:16 +0200 Subject: Process http request before send it to the proxy In-Reply-To: References: Message-ID: <54ac879efb2dadb6a82b941ae4891ebb@sebres.de> Hi, If you want parse/modify request data before you pass it to upstream, take a look at NGINX-UPLOAD-MODULE, that do it similar way you may need - reads request (POST/multipart), save file-data into temp-file(s), and rewrite arguments pointing to this new file(s). If you want rather to do something like external authorization, the handling like `auth_request` from `NGX_HTTP_AUTH_REQUEST_MODULE` may be interesting for you. > Should i use a handler or a filter in order to work with proxy_pass? Filters mostly modify response resp. do the replacement in response body/header (that will be already received from upstream via proxy_pass), so it would be too late in your case. Regards, sebres Am 02.05.2017 00:17, schrieb Aris Striglis: > Hello! > > I'm new to nginx, playing using the api and making some handlers and filters. Now what i would like to do is to > > process the request headers, call an external c library, do some work and pass the request to an upstream using proxy_pass. > > I read about http request processing phases and handler priority, but i am a little bit confused. > > Should i use a handler or a filter in order to work with proxy_pass? > > Thanks. > > aris > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel [1] Links: ------ [1] http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Wed May 3 14:00:18 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 3 May 2017 17:00:18 +0300 Subject: [PATCH 1 of 3] HTTP: add support for trailers in HTTP responses In-Reply-To: References: <8af81a0d66c0f69bcf50.1491211931@piotrsikora.sfo.corp.google.com> <20170421174201.GA43932@mdounin.ru> <20170427184623.GD43932@mdounin.ru> Message-ID: <20170503140018.GN43932@mdounin.ru> Hello! On Sun, Apr 30, 2017 at 09:37:36PM -0700, Piotr Sikora via nginx-devel wrote: > Hey Maxim, > > > As you can see from the quote, it talks about not generating > > "trailer fields that it believes are necessary for the user agent > > to receive". RFC 2616 is even more clear on this, specifically > > lists two cases when trailers can be generated, section 3.6.1: > > > > A server using chunked transfer-coding in a response MUST NOT use the > > trailer for any header fields unless at least one of the following is > > true: > > > > a)the request included a TE header field that indicates "trailers" is > > acceptable in the transfer-coding of the response, as described in > > section 14.39; or, > > > > b)the server is the origin server for the response, the trailer > > fields consist entirely of optional metadata, and the recipient > > could use the message (in a manner acceptable to the origin server) > > without receiving this metadata. In other words, the origin server > > is willing to accept the possibility that the trailer fields might > > be silently discarded along the path to the client. > > > > That is, there clearly two cases when a server can / should send > > trailers: > > > > - when there is "TE: trailers"; > > > > - when trailers are optional. > > > > Moreover, given that "TE: trailers" does _not_ guarantee anything > > either (see link above), the only remaining case seems to be "when > > trailers are optional". > > I disagree, if someone adds trailers in their configuration, then they > are hardly optional, therefore they should be sent in response to > requests with "TE: trailers". I don't think that deciding for users is a good idea, especially given that the only available case is "when trailers are optional" (see above, "TE: trailers" does not guarantee anything) and all three use cases listed also assume that trailers are optional. > > As per previous discussion, main cases, as listed by you, are: > > > > 1. Checksums, like Content-SHA256. > > 2. Logging, like X-Log-Something for centralized logging on a > > frontend. > > 3. Trailing status, like X-Status, to provide additional error > > information to a frontend. > > > > All these uses cases hardly require "TE: trailers", as in all > > cases information seems optional. Moreover, in cases (2) and (3), > > backend cannot have "TE: trailers" unless it was already present > > in the original request from the client. Adding such a header > > would contradict RFC 7230, which says: > > > > The presence of the keyword "trailers" indicates that the client is > > willing to accept trailer fields in a chunked transfer coding, as > > defined in Section 4.1.2, on behalf of itself and any downstream > > clients. For requests from an intermediary, this implies that > > either: (a) all downstream clients are willing to accept trailer > > fields in the forwarded response; or, (b) the intermediary will > > attempt to buffer the response on behalf of downstream recipients. > > > > So both cases (2) and (3) generally require that "TE: trailers" > > should be ignored, or it won't be possible to implement them. > > That's valid argument. Good to see you've finally got the idea. That's what I'm trying to say all the time: if "TE: trailers" should be considered or not depends on the use case. In all use cases listed so far it should be ignored. It is also possible that there are some use cases when trailers are to be added only with "TE: trailers". It should be possible to only add trailers for such use cases based on a configure test though. (And I really don't think such use cases are in fact possible given the problems outlined above.) > > Current nginx behaviour is to don't emit trailers by default, and > > I don't think we anyhow change this beaviour unless explicitly > > requested via appropriate configuration directives. This looks > > conservative enough for me, actually. > > Yes, of course. What I meant is that if some module produces trailers > and it's enabled in the configuration, then even if there are only few > obscure clients that break because of it, the only option will be to > disable them altogether, instead of only sending them in response to > requests with "TE: trailers". > > Anyway, I'll just remove that requirement for now, and you can re-add > it later if/when others complain. Well, this looks like a problem specific to the particular module and/or particular trailer being added. And certainly re-adding won't work, as we've already agreed that at least some use cases require trailers regardless of "TE: trailers". > > I can see that r->expect_trailers can be useful to indicate that > > the code wants to use trailers, and would like to force chunked > > encoding if possible. > > > > I don't see why it should be required when encoding is already > > choosen though. If we know that we can use trailers or don't > > care, we can just add trailers to the response, and assume they > > will be sent if it is possible to do so. > > I'm confused, it sounds like you're saying two opposite things... > > Are you saying that r->expect_trailers should be removed and we should > send trailers only if transfer encoding is already chunked and not > send trailers otherwise? No. In your patch, you test r->expect_trailers in two places in chunked filter: 1. when you decide whether to use chunked encoding or not, in ngx_http_chunked_header_filter(); 2. when you generate trailer, in ngx_http_chunked_body_filter(). I mostly agree with (1) (I would like see it configurable too, but it's probably up to a module which adds trailers to decide, so don't belong to this particular patch), but don't see any reasons for (2). > > As per HTTP specification, trailers are expected to be sent as > > normal headers when there is no body, for both HTTP/1.1 and > > HTTP/2. And I suspect that the fact that HTTP/2 allows two > > HEADERS frames without body inbetween is more or less > > unintentional, too. > > > > (...) > > > > I certainly against intruduction of such a difference between > > HTTP/1.1 and HTTP/2 behaviour. > > So what do you suggest we do instead? Merge them with headers? Wasn't > that your biggest concern from the beginning? Certainly merging is a bad idea either. May be the solution would be avoid sending trailers for header-only requests consistently for both HTTP/1.1 and HTTP/2. > Also, how would you merge them in upstream? Cacheable responses to > HEAD requests are "terminated" and headers are sent before upstream > sends complete response, so trailers would be dropped there (at least > in the existing code). Yes, certainly it won't be possible to implement this without major changes to the current code. And, even if properly implemented, this will require buffering of the whole backend response before nginx will be able to answer to the client, so probably this is not something we want to deal with. Note well that this problem is protocol-independent, so it will also affect sending trailers in HTTP/2 for header-only requests as currently done in your patch. Just a side note: another related problem is with trailers calculated by body filters, such as Content-SHA256. There are no body filters in case of header-only requests, so such filters won't be able calculate anything. -- Maxim Dounin http://nginx.org/ From pluknet at nginx.com Thu May 4 09:34:23 2017 From: pluknet at nginx.com (Sergey Kandaurov) Date: Thu, 04 May 2017 09:34:23 +0000 Subject: [nginx] SSL: allowed renegotiation in client mode with OpenSSL < 1.1.0. Message-ID: details: http://hg.nginx.org/nginx/rev/eb5d119323d8 branches: changeset: 6995:eb5d119323d8 user: Sergey Kandaurov date: Wed May 03 15:15:56 2017 +0300 description: SSL: allowed renegotiation in client mode with OpenSSL < 1.1.0. In ac9b1df5b246 (1.13.0) we attempted to allow renegotiation in client mode, but when using OpenSSL 1.0.2 or older versions it was additionally disabled by SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS. diffstat: src/event/ngx_event_openssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r f38647c651a8 -r eb5d119323d8 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Thu Apr 27 16:57:18 2017 +0300 +++ b/src/event/ngx_event_openssl.c Wed May 03 15:15:56 2017 +0300 @@ -1300,7 +1300,7 @@ ngx_ssl_handshake(ngx_connection_t *c) #ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS /* initial handshake done, disable renegotiation (CVE-2009-3555) */ - if (c->ssl->connection->s3) { + if (c->ssl->connection->s3 && SSL_is_server(c->ssl->connection)) { c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; } From BenBE at geshi.org Fri May 5 07:54:03 2017 From: BenBE at geshi.org (Benny Baumann) Date: Fri, 5 May 2017 09:54:03 +0200 Subject: New variable $ssl_raw_handshake Message-ID: Hi, in course of building up a dataset of mappings of User-Agents and their common SSL ClientHello messages[1] I started to implement a small patch to nginx 1.13.0 mainline to implement a small transcript of the handshake process similar to the one enabled in openssl s_client -msg. The format of this new variable is a series of semicolon-delimited blocks starting with a direction (C: -> sent by client, S: -> sent by server) and followed by colon-delimited hexdumps of processed blocks of data. The string C:00:01;S:0203:0405:0607;C:08090A; denotes 2 blocks of 1 byte each sent by the client, followed by 3 blocks 2 byte each from the server and finally 1 block of 3 bytes from the client. Blocks usually conform to how OpenSSL tries to process the data. I'd appreciate a short review of the patch with comments for possible improvements, code style and other related things. One yet open aspect is configurable behaviour to only enable collection on-demand. Also ideas for migrating this code into a separate module are welcome. NB: Due to size of transcribed information it is commonly not feasible to pass this variable to other backend servers via HTTP headers. Trying to do so will most likely result in the backend responding 400 Bad Request, sometimes also remarking about the overlong header. I'm still looking at ways how this can be done in a sane way (abusing memcached for transporting could be an option) - but this is outside the scope of this patch. Plainly logging the information of this header to some custom log will do just fine. Kind regards, BenBE. [1] Original paper on this approach at [2] [2] https://jhalderm.com/pub/papers/interception-ndss17.pdf -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-add-Transcript-of-SSL-Handshake-similar-to-openssl-s.patch Type: text/x-patch Size: 5669 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From janusz.m at gmail.com Sat May 13 19:11:13 2017 From: janusz.m at gmail.com (Janusz M) Date: Sat, 13 May 2017 21:11:13 +0200 Subject: proxy_protocol_port variable should store the PROXY_PORT rather than CLIENT_PORT Message-ID: I'd expect to see the original request's port 80 or 443 in this variable rather than relatively useless (IMHO) CLIENT_PORT which looks like 51501. A typical use case for this change would look like the following: 1. nginx HTTP server is running behind Amazon Load Balancer in TCP mode with PROXY PROTOCOL enabled (can be any TCP load balancer with proxy protocol on, useful for websockets for example) 2. nginx has the proxy_protocol turned on 3. we (or other apps, upstream servers) want to know what was the ORIGINAL port/protocol of the incoming request (eg. was it 80/HTTP or 443/HTTPS). Currently it seems that it's impossible to get the request port/protocol value from nginx behind tcp load balancer. If nginx stored the PROXY_PORT instead of the CLIENT_PORT value in that (or another) variable it would be extremely easy for other apps to know the original port/protocol. >>> server { listen 80 proxy_protocol; ... proxy_set_header X-Forwarded-Port $proxy_protocol_port; # 51505 instead of 443/80 !! } Please let me know if it's feasible or planned, or if we could actually read the original incoming request port in a different way -------------- next part -------------- An HTML attachment was scrubbed... URL: From janusz.m at gmail.com Sat May 13 21:35:24 2017 From: janusz.m at gmail.com (Janusz M) Date: Sat, 13 May 2017 23:35:24 +0200 Subject: proxy_protocol_port variable should store the PROXY_PORT rather than CLIENT_PORT Message-ID: The problem with reading the correct port seems to be with nginx at src/core/ngx_proxy_protocol.c somewhere between lines 70 and 120 , It just reads the PROXY line, takes the first IP as the client IP and then skips to ports and takes the first port. Instead it should skip the first one and take the last according to Proxy Protocol specs. See example mentioned before: PROXY TCP4 192.168.0.1 192.168.0.11 56324 443 -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Mon May 15 13:17:31 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 15 May 2017 16:17:31 +0300 Subject: proxy_protocol_port variable should store the PROXY_PORT rather than CLIENT_PORT In-Reply-To: References: Message-ID: <20170515131731.GZ55433@mdounin.ru> Hello! On Sat, May 13, 2017 at 09:11:13PM +0200, Janusz M wrote: > I'd expect to see the original request's port 80 or 443 in this variable > rather than relatively useless (IMHO) CLIENT_PORT which looks like 51501. The $proxy_protocol_port, much like $proxy_protocol_addr, reflects client port for the proxy protocol header. It is to be used (again, much like $proxy_protocol_addr) to log original client's port, which is needed to trace a particular client. It also can be used in X-Real-IP / X-Forwarded-For to pass the port to upstream servers. Quoting nginx 1.11.0 changes: *) Feature: the $proxy_protocol_port variable. *) Feature: the $realip_remote_port variable in the ngx_http_realip_module. *) Feature: the ngx_http_realip_module is now able to set the client port in addition to the address. Hope this help to understand how it is expected to be used. > A typical use case for this change would look like the following: > > 1. nginx HTTP server is running behind Amazon Load Balancer in TCP mode > with PROXY PROTOCOL enabled (can be any TCP load balancer with proxy > protocol on, useful for websockets for example) > 2. nginx has the proxy_protocol turned on > 3. we (or other apps, upstream servers) want to know what was the ORIGINAL > port/protocol of the incoming request (eg. was it 80/HTTP or 443/HTTPS). > > Currently it seems that it's impossible to get the request port/protocol > value from nginx behind tcp load balancer. If nginx stored the PROXY_PORT > instead of the CLIENT_PORT value in that (or another) variable it would be > extremely easy for other apps to know the original port/protocol. > > >>> > server { > listen 80 proxy_protocol; > ... > proxy_set_header X-Forwarded-Port $proxy_protocol_port; # 51505 instead > of 443/80 !! > } This is a completely different use case. Moreover, this use case can be easily avoided by forwarding connections to different ports within nginx. And so, quoting your own words, "relatively useless". > Please let me know if it's feasible or planned, or if we could actually > read the original incoming request port in a different way No, there are no plans to change current behaviour. -- Maxim Dounin http://nginx.org/ From janusz.m at gmail.com Mon May 15 14:00:07 2017 From: janusz.m at gmail.com (Janusz M) Date: Mon, 15 May 2017 16:00:07 +0200 Subject: proxy_protocol_port variable should store the PROXY_PORT rather than CLIENT_PORT In-Reply-To: <20170515131731.GZ55433@mdounin.ru> References: <20170515131731.GZ55433@mdounin.ru> Message-ID: Hi Maxim, First of all thanks for your quick reply. I read the nginx 1.11.0 and 1.11.4 release notes, thanks. Perhaps I wasn't as clear in my description as possible. Please consider the following scenario: * a client (user) with IP 185.12.12.12 makes an HTTPS request to the app and hits the load balancer * load balancer forwards both HTTP and HTTPS requests to nginx server on port 80 (standard Amazon AWS setup) * Proxy Protocol is turned on, load balancer adds the following line to the request: PROXY TCP4 185.12.12.12 172.31.0.11 56324 443 * nginx with proxy_protocol on reads port 56324 to $proxy_protocol_port. The point is that with the current implementation, either nginx's behaviour or proxy protocol itself feels inconsistent. You wrote: "The $proxy_protocol_port, much like $proxy_protocol_addr, reflects client port for the proxy protocol header. " but in fact, what we see in those variables is the client IP (public IP of the client's computer) and the load balancer port (not the client port). What I meant by "relatively useless" is that I'd expect that in most cases people/apps care about the last value in the proxy protocol line, that is 443 in the above example. The code in src/core/ngx_proxy_protocol.c reads the first IP in that line and then skips to the first port number found. Don't you think that to read the 'client port' nginx should read the last port number in the line? PS. I actually resolved my current issue by forwarding connections to different ports within nginx. 2017-05-15 15:17 GMT+02:00 Maxim Dounin : > Hello! > > On Sat, May 13, 2017 at 09:11:13PM +0200, Janusz M wrote: > > > I'd expect to see the original request's port 80 or 443 in this variable > > rather than relatively useless (IMHO) CLIENT_PORT which looks like 51501. > > The $proxy_protocol_port, much like $proxy_protocol_addr, reflects > client port for the proxy protocol header. It is to be used > (again, much like $proxy_protocol_addr) to log original client's port, > which is needed to trace a particular client. It also can be used in > X-Real-IP / X-Forwarded-For to pass the port to upstream servers. > Quoting nginx 1.11.0 changes: > > *) Feature: the $proxy_protocol_port variable. > > *) Feature: the $realip_remote_port variable in the > ngx_http_realip_module. > > *) Feature: the ngx_http_realip_module is now able to set the client > port in addition to the address. > > Hope this help to understand how it is expected to be used. > > > A typical use case for this change would look like the following: > > > > 1. nginx HTTP server is running behind Amazon Load Balancer in TCP mode > > with PROXY PROTOCOL enabled (can be any TCP load balancer with proxy > > protocol on, useful for websockets for example) > > 2. nginx has the proxy_protocol turned on > > 3. we (or other apps, upstream servers) want to know what was the > ORIGINAL > > port/protocol of the incoming request (eg. was it 80/HTTP or 443/HTTPS). > > > > Currently it seems that it's impossible to get the request port/protocol > > value from nginx behind tcp load balancer. If nginx stored the PROXY_PORT > > instead of the CLIENT_PORT value in that (or another) variable it would > be > > extremely easy for other apps to know the original port/protocol. > > > > >>> > > server { > > listen 80 proxy_protocol; > > ... > > proxy_set_header X-Forwarded-Port $proxy_protocol_port; # 51505 > instead > > of 443/80 !! > > } > > This is a completely different use case. Moreover, this use case > can be easily avoided by forwarding connections to different > ports within nginx. And so, quoting your own words, "relatively > useless". > > > Please let me know if it's feasible or planned, or if we could actually > > read the original incoming request port in a different way > > No, there are no plans to change current behaviour. > > -- > 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 ru at nginx.com Mon May 15 14:21:16 2017 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 15 May 2017 14:21:16 +0000 Subject: [nginx] Access: simplified rule parser code. Message-ID: details: http://hg.nginx.org/nginx/rev/72188d1bcab5 branches: changeset: 6996:72188d1bcab5 user: Ruslan Ermilov date: Mon May 15 17:16:32 2017 +0300 description: Access: simplified rule parser code. diffstat: src/http/modules/ngx_http_access_module.c | 20 +++++++------------- src/stream/ngx_stream_access_module.c | 20 +++++++------------- 2 files changed, 14 insertions(+), 26 deletions(-) diffs (76 lines): diff -r eb5d119323d8 -r 72188d1bcab5 src/http/modules/ngx_http_access_module.c --- a/src/http/modules/ngx_http_access_module.c Wed May 03 15:15:56 2017 +0300 +++ b/src/http/modules/ngx_http_access_module.c Mon May 15 17:16:32 2017 +0300 @@ -309,27 +309,21 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx ngx_http_access_rule_un_t *rule_un; #endif + all = 0; ngx_memzero(&cidr, sizeof(ngx_cidr_t)); value = cf->args->elts; - all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0); - - if (!all) { + if (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0) { + all = 1; #if (NGX_HAVE_UNIX_DOMAIN) - - if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { - cidr.family = AF_UNIX; - rc = NGX_OK; + } else if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { + cidr.family = AF_UNIX; +#endif - } else { - rc = ngx_ptocidr(&value[1], &cidr); - } - -#else + } else { rc = ngx_ptocidr(&value[1], &cidr); -#endif if (rc == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, diff -r eb5d119323d8 -r 72188d1bcab5 src/stream/ngx_stream_access_module.c --- a/src/stream/ngx_stream_access_module.c Wed May 03 15:15:56 2017 +0300 +++ b/src/stream/ngx_stream_access_module.c Mon May 15 17:16:32 2017 +0300 @@ -299,27 +299,21 @@ ngx_stream_access_rule(ngx_conf_t *cf, n ngx_stream_access_rule_un_t *rule_un; #endif + all = 0; ngx_memzero(&cidr, sizeof(ngx_cidr_t)); value = cf->args->elts; - all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0); - - if (!all) { + if (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0) { + all = 1; #if (NGX_HAVE_UNIX_DOMAIN) - - if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { - cidr.family = AF_UNIX; - rc = NGX_OK; + } else if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { + cidr.family = AF_UNIX; +#endif - } else { - rc = ngx_ptocidr(&value[1], &cidr); - } - -#else + } else { rc = ngx_ptocidr(&value[1], &cidr); -#endif if (rc == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, From ru at nginx.com Mon May 15 14:21:18 2017 From: ru at nginx.com (Ruslan Ermilov) Date: Mon, 15 May 2017 14:21:18 +0000 Subject: [nginx] Realip: allow hostnames in set_real_ip_from (ticket #1180). Message-ID: details: http://hg.nginx.org/nginx/rev/df1a62c83b1b branches: changeset: 6997:df1a62c83b1b user: Ruslan Ermilov date: Mon May 15 17:17:01 2017 +0300 description: Realip: allow hostnames in set_real_ip_from (ticket #1180). diffstat: src/http/modules/ngx_http_realip_module.c | 83 +++++++++++++++++++++++++----- src/stream/ngx_stream_realip_module.c | 83 +++++++++++++++++++++++++----- 2 files changed, 136 insertions(+), 30 deletions(-) diffs (226 lines): diff -r 72188d1bcab5 -r df1a62c83b1b src/http/modules/ngx_http_realip_module.c --- a/src/http/modules/ngx_http_realip_module.c Mon May 15 17:16:32 2017 +0300 +++ b/src/http/modules/ngx_http_realip_module.c Mon May 15 17:17:01 2017 +0300 @@ -317,9 +317,15 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx { ngx_http_realip_loc_conf_t *rlcf = conf; - ngx_int_t rc; - ngx_str_t *value; - ngx_cidr_t *cidr; + ngx_int_t rc; + ngx_str_t *value; + ngx_url_t u; + ngx_cidr_t c, *cidr; + ngx_uint_t i; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif value = cf->args->elts; @@ -331,31 +337,78 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx } } - cidr = ngx_array_push(rlcf->from); - if (cidr == NULL) { - return NGX_CONF_ERROR; - } - #if (NGX_HAVE_UNIX_DOMAIN) if (ngx_strcmp(value[1].data, "unix:") == 0) { + cidr = ngx_array_push(rlcf->from); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + cidr->family = AF_UNIX; return NGX_CONF_OK; } #endif - rc = ngx_ptocidr(&value[1], cidr); + rc = ngx_ptocidr(&value[1], &c); - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", - &value[1]); + if (rc != NGX_ERROR) { + if (rc == NGX_DONE) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "low address bits of %V are meaningless", + &value[1]); + } + + cidr = ngx_array_push(rlcf->from); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + + *cidr = c; + + return NGX_CONF_OK; + } + + ngx_memzero(&u, sizeof(ngx_url_t)); + u.host = value[1]; + + if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { + if (u.err) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "%s in set_real_ip_from \"%V\"", + u.err, &u.host); + } + return NGX_CONF_ERROR; } - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", &value[1]); + cidr = ngx_array_push_n(rlcf->from, u.naddrs); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t)); + + for (i = 0; i < u.naddrs; i++) { + cidr[i].family = u.addrs[i].sockaddr->sa_family; + + switch (cidr[i].family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr; + cidr[i].u.in6.addr = sin6->sin6_addr; + ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16); + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) u.addrs[i].sockaddr; + cidr[i].u.in.addr = sin->sin_addr.s_addr; + cidr[i].u.in.mask = 0xffffffff; + break; + } } return NGX_CONF_OK; diff -r 72188d1bcab5 -r df1a62c83b1b src/stream/ngx_stream_realip_module.c --- a/src/stream/ngx_stream_realip_module.c Mon May 15 17:16:32 2017 +0300 +++ b/src/stream/ngx_stream_realip_module.c Mon May 15 17:17:01 2017 +0300 @@ -178,9 +178,15 @@ ngx_stream_realip_from(ngx_conf_t *cf, n { ngx_stream_realip_srv_conf_t *rscf = conf; - ngx_int_t rc; - ngx_str_t *value; - ngx_cidr_t *cidr; + ngx_int_t rc; + ngx_str_t *value; + ngx_url_t u; + ngx_cidr_t c, *cidr; + ngx_uint_t i; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif value = cf->args->elts; @@ -192,31 +198,78 @@ ngx_stream_realip_from(ngx_conf_t *cf, n } } - cidr = ngx_array_push(rscf->from); - if (cidr == NULL) { - return NGX_CONF_ERROR; - } - #if (NGX_HAVE_UNIX_DOMAIN) if (ngx_strcmp(value[1].data, "unix:") == 0) { + cidr = ngx_array_push(rscf->from); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + cidr->family = AF_UNIX; return NGX_CONF_OK; } #endif - rc = ngx_ptocidr(&value[1], cidr); + rc = ngx_ptocidr(&value[1], &c); - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", - &value[1]); + if (rc != NGX_ERROR) { + if (rc == NGX_DONE) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "low address bits of %V are meaningless", + &value[1]); + } + + cidr = ngx_array_push(rscf->from); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + + *cidr = c; + + return NGX_CONF_OK; + } + + ngx_memzero(&u, sizeof(ngx_url_t)); + u.host = value[1]; + + if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { + if (u.err) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "%s in set_real_ip_from \"%V\"", + u.err, &u.host); + } + return NGX_CONF_ERROR; } - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", &value[1]); + cidr = ngx_array_push_n(rscf->from, u.naddrs); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t)); + + for (i = 0; i < u.naddrs; i++) { + cidr[i].family = u.addrs[i].sockaddr->sa_family; + + switch (cidr[i].family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr; + cidr[i].u.in6.addr = sin6->sin6_addr; + ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16); + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) u.addrs[i].sockaddr; + cidr[i].u.in.addr = sin->sin_addr.s_addr; + cidr[i].u.in.mask = 0xffffffff; + break; + } } return NGX_CONF_OK; From mdounin at mdounin.ru Mon May 15 15:04:22 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 15 May 2017 18:04:22 +0300 Subject: proxy_protocol_port variable should store the PROXY_PORT rather than CLIENT_PORT In-Reply-To: References: <20170515131731.GZ55433@mdounin.ru> Message-ID: <20170515150422.GC55433@mdounin.ru> Hello! On Mon, May 15, 2017 at 04:00:07PM +0200, Janusz M wrote: > Hi Maxim, > > First of all thanks for your quick reply. I read the nginx 1.11.0 and > 1.11.4 release notes, thanks. Perhaps I wasn't as clear in my description > as possible. > > Please consider the following scenario: > > * a client (user) with IP 185.12.12.12 makes an HTTPS request to the app > and hits the load balancer > * load balancer forwards both HTTP and HTTPS requests to nginx server on > port 80 (standard Amazon AWS setup) > * Proxy Protocol is turned on, load balancer adds the following line to the > request: > > PROXY TCP4 185.12.12.12 172.31.0.11 56324 443 So, as per PROXY protocol specification, source address is 185.12.12.12, source port is 56324. Destination address is 172.31.0.11, destination port is 443. > * nginx with proxy_protocol on reads port 56324 to $proxy_protocol_port. > > > The point is that with the current implementation, either nginx's behaviour > or proxy protocol itself feels inconsistent. > You wrote: > "The $proxy_protocol_port, much like $proxy_protocol_addr, reflects client > port for the proxy protocol header. " > but in fact, what we see in those variables is the client IP (public IP of > the client's computer) and the load balancer port (not the client port). When the original client connection uses 185.12.12.12 source address and 56324 source port, $proxy_protocol_addr will contain 185.12.12.12, and $proxy_protocol_port will contain 56324. This is perfectly consistent and will allow to uniquely identify client even if it is behind a NAT or we need to find out a particular process which established the connection. Both destination address and destination port are not available via nginx variables. As previously suggested, if you want to distinguish between different destinations, you can easily do so by using distinct listening sockets in nginx. It looks like you somehow think that "client port" means "the port which client used as a destination of a connection". This is certainly not what it used to mean. Each TCP connection has two sides, and each side has an address and a port. When one of the sides is a client, "client address" is the address of this side, and "client port" is the port of this side. Please refer to TCP protocol description for more information. -- Maxim Dounin http://nginx.org/ From janusz.m at gmail.com Mon May 15 15:13:49 2017 From: janusz.m at gmail.com (Janusz M) Date: Mon, 15 May 2017 17:13:49 +0200 Subject: proxy_protocol_port variable should store the PROXY_PORT rather than CLIENT_PORT In-Reply-To: <20170515150422.GC55433@mdounin.ru> References: <20170515131731.GZ55433@mdounin.ru> <20170515150422.GC55433@mdounin.ru> Message-ID: Thanks for the detailed description! The use case that you described explains all: "... to uniquely identify client even if it is behind a NAT or we need to find out a particular process which established the connection." Both 56324 and 443 values could be used in certain scenarios and now we'd need to introduce new variable to satisfy all valid use cases. Perhaps this could evolve into a new feature and new var? Kind regards, Janusz 2017-05-15 17:04 GMT+02:00 Maxim Dounin : > Hello! > > On Mon, May 15, 2017 at 04:00:07PM +0200, Janusz M wrote: > > > Hi Maxim, > > > > First of all thanks for your quick reply. I read the nginx 1.11.0 and > > 1.11.4 release notes, thanks. Perhaps I wasn't as clear in my description > > as possible. > > > > Please consider the following scenario: > > > > * a client (user) with IP 185.12.12.12 makes an HTTPS request to the app > > and hits the load balancer > > * load balancer forwards both HTTP and HTTPS requests to nginx server on > > port 80 (standard Amazon AWS setup) > > * Proxy Protocol is turned on, load balancer adds the following line to > the > > request: > > > > PROXY TCP4 185.12.12.12 172.31.0.11 56324 443 > > So, as per PROXY protocol specification, source address is > 185.12.12.12, source port is 56324. Destination address is > 172.31.0.11, destination port is 443. > > > * nginx with proxy_protocol on reads port 56324 to $proxy_protocol_port. > > > > > > The point is that with the current implementation, either nginx's > behaviour > > or proxy protocol itself feels inconsistent. > > You wrote: > > "The $proxy_protocol_port, much like $proxy_protocol_addr, reflects > client > > port for the proxy protocol header. " > > but in fact, what we see in those variables is the client IP (public IP > of > > the client's computer) and the load balancer port (not the client port). > > When the original client connection uses 185.12.12.12 source > address and 56324 source port, $proxy_protocol_addr will contain > 185.12.12.12, and $proxy_protocol_port will contain 56324. This > is perfectly consistent and will allow to uniquely identify client > even if it is behind a NAT or we need to find out a particular > process which established the connection. > > Both destination address and destination port are not available > via nginx variables. As previously suggested, if you want to > distinguish between different destinations, you can easily do so > by using distinct listening sockets in nginx. > > It looks like you somehow think that "client port" means "the port > which client used as a destination of a connection". This is > certainly not what it used to mean. Each TCP connection has two > sides, and each side has an address and a port. When one of the > sides is a client, "client address" is the address of this side, > and "client port" is the port of this side. Please refer to TCP > protocol description for more information. > > -- > 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 mdounin at mdounin.ru Mon May 15 17:50:58 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 15 May 2017 17:50:58 +0000 Subject: [nginx] Configure: style. Message-ID: details: http://hg.nginx.org/nginx/rev/775f621eacae branches: changeset: 6998:775f621eacae user: Maxim Dounin date: Mon May 15 20:09:40 2017 +0300 description: Configure: style. diffstat: auto/cc/conf | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff --git a/auto/cc/conf b/auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -209,7 +209,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then var(0, buf, \"%d\", 1); if (buf[0] != '1') return 1" . auto/feature - fi + fi ngx_feature="gcc variadic macros" From mdounin at mdounin.ru Mon May 15 17:51:02 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 15 May 2017 17:51:02 +0000 Subject: [nginx] Configure: disabled gcc atomics with Sun C (ticket #1261). Message-ID: details: http://hg.nginx.org/nginx/rev/4925a6d13746 branches: changeset: 6999:4925a6d13746 user: Maxim Dounin date: Mon May 15 20:09:43 2017 +0300 description: Configure: disabled gcc atomics with Sun C (ticket #1261). Oracle Developer Studio 12.5 introduced GCC-compatible __sync builtins. Unfortunately, these builtins are neither GCC-compatible (they generate warnings when used with volatile), nor working (unexpectedly fail on unpredictable combinations of code layout and compiler flags). As such, the gcc builtin atomic operations configure test explicitly disabled when compiling with Sun C. diffstat: auto/cc/conf | 34 +++++++++++++++++++--------------- 1 files changed, 19 insertions(+), 15 deletions(-) diffs (44 lines): diff --git a/auto/cc/conf b/auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -178,21 +178,25 @@ if [ "$NGX_PLATFORM" != win32 ]; then fi - ngx_feature="gcc builtin atomic operations" - ngx_feature_name=NGX_HAVE_GCC_ATOMIC - ngx_feature_run=yes - ngx_feature_incs= - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="long n = 0; - if (!__sync_bool_compare_and_swap(&n, 0, 1)) - return 1; - if (__sync_fetch_and_add(&n, 1) != 1) - return 1; - if (n != 2) - return 1; - __sync_synchronize();" - . auto/feature + if [ "$NGX_CC_NAME" = "sunc" ]; then + echo "checking for gcc builtin atomic operations ... disabled" + else + ngx_feature="gcc builtin atomic operations" + ngx_feature_name=NGX_HAVE_GCC_ATOMIC + ngx_feature_run=yes + ngx_feature_incs= + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="long n = 0; + if (!__sync_bool_compare_and_swap(&n, 0, 1)) + return 1; + if (__sync_fetch_and_add(&n, 1) != 1) + return 1; + if (n != 2) + return 1; + __sync_synchronize();" + . auto/feature + fi if [ "$NGX_CC_NAME" = "ccc" ]; then From mdounin at mdounin.ru Mon May 15 17:51:04 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 15 May 2017 17:51:04 +0000 Subject: [nginx] Configure: recent Sun C versions. Message-ID: details: http://hg.nginx.org/nginx/rev/d8e8ced78e77 branches: changeset: 7000:d8e8ced78e77 user: Maxim Dounin date: Mon May 15 20:09:44 2017 +0300 description: Configure: recent Sun C versions. diffstat: auto/cc/sunc | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (15 lines): diff --git a/auto/cc/sunc b/auto/cc/sunc --- a/auto/cc/sunc +++ b/auto/cc/sunc @@ -8,7 +8,10 @@ # Sun C 5.9 SunOS_i386 2007/05/03 Sun Studio 12 # Sun C 5.9 SunOS_sparc 2007/05/03 # Sun C 5.10 SunOS_i386 2009/06/03 Sun Studio 12.1 -# Sun C 5.11 SunOS_i386 2010/08/13 Sun Studio 12.2 +# Sun C 5.11 SunOS_i386 2010/08/13 Oracle Solaris Studio 12.2 +# Sun C 5.12 SunOS_i386 2011/11/16 Oracle Solaris Studio 12.3 +# Sun C 5.13 SunOS_i386 2014/10/20 Oracle Solaris Studio 12.4 +# Sun C 5.14 SunOS_i386 2016/05/31 Oracle Developer Studio 12.5 NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \ | sed -e 's/^.* Sun C \(.*\)/\1/'` From prabhashrathore at gmail.com Tue May 16 18:18:27 2017 From: prabhashrathore at gmail.com (Prabhash Rathore) Date: Tue, 16 May 2017 18:18:27 +0000 Subject: How to make nginx mail auth connection persistent? Message-ID: Hello, We are using nginx 1.7.3 as a reverse proxy for our Mail SMTP service. For authentication of each SMTP connection, we have configured nginx to connect with a http based service for authentication. Here is a snippet of our nginx config: mail { # auth_server auth_http auth_host:auth_port/authserver; # mail server server { protocol smtp; listen 25; proxy on; xclient on; timeout 15; starttls on; ... other configs... } } With above config, we notice that nginx closes the connection after every auth request/response to Mail Authentication Server (auth_http auth_host:auth_port/authserver;) based on tcpdump analysis. We would like to make this connection persistent so that we could reuse connection for multiple auth requests. I looked at nginx mail auth module documentation ( http://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#auth_http_header ) but I don't see any directive to make mail auth connection persistent. I also looked at ngx_http_upstream_module ( http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) which has "keepalive" directive but my understanding is this directive is for http upstream server not for mail auth server. Can someone please help? Thanks! -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue May 16 18:26:09 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 16 May 2017 21:26:09 +0300 Subject: How to make nginx mail auth connection persistent? In-Reply-To: References: Message-ID: <20170516182609.GN55433@mdounin.ru> Hello! On Tue, May 16, 2017 at 06:18:27PM +0000, Prabhash Rathore wrote: > We are using nginx 1.7.3 as a reverse proxy for our Mail SMTP service. For > authentication of each SMTP connection, we have configured nginx to connect > with a http based service for authentication. Here is a snippet of our > nginx config: > > mail { > # auth_server > auth_http auth_host:auth_port/authserver; > > # mail server > server { > protocol smtp; > listen 25; > proxy on; > xclient on; > timeout 15; > starttls on; > ... other configs... > } > } > > With above config, we notice that nginx closes the connection after every > auth request/response to Mail Authentication Server (auth_http > auth_host:auth_port/authserver;) based on tcpdump analysis. We would like > to make this connection persistent so that we could reuse connection for > multiple auth requests. > > I looked at nginx mail auth module documentation ( > http://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#auth_http_header > ) but I don't see any directive to make mail auth connection persistent. The auth_http module uses HTTP/1.0 and has no keepalive connections support. If there are practical reasons why you want it to use keepalive, a simple http proxy within the same nginx server will likely help. -- Maxim Dounin http://nginx.org/ From prabhashrathore at gmail.com Tue May 16 21:29:26 2017 From: prabhashrathore at gmail.com (Prabhash Rathore) Date: Tue, 16 May 2017 21:29:26 +0000 Subject: How to make nginx mail auth connection persistent? In-Reply-To: <20170516182609.GN55433@mdounin.ru> References: <20170516182609.GN55433@mdounin.ru> Message-ID: Hi Maxim, Thank you for your response! Our Mail backend system receives millions of SMTP connection requests every day and for each connection request, we need to establish new connection with auth server and then tear it down which is an overhead on CPU and network. So we are looking on ways to use HTTP1.1 persistent connection so that we can save on our resources by reusing connections. I think it will be a nice feature to have in nginx? By the way, is there a reason why nginx auth_http does not support http 1.1? Based on your suggestion, I tried following configuration but this did not work. Nginx will not start complaining about unknown upstream and location directives. upstream tss { server host_name:port/smtp.php; keepalive 32; } location / { proxy_http_version 1.1; proxy_pass http://tss; } mail { # auth auth_http tss; } Could you please share sample proxy config which could be used to enable keepalive for auth_http? Thanks! Prabhash Rathore On Tue, May 16, 2017 at 11:26 AM Maxim Dounin wrote: > Hello! > > On Tue, May 16, 2017 at 06:18:27PM +0000, Prabhash Rathore wrote: > > > We are using nginx 1.7.3 as a reverse proxy for our Mail SMTP service. > For > > authentication of each SMTP connection, we have configured nginx to > connect > > with a http based service for authentication. Here is a snippet of our > > nginx config: > > > > mail { > > # auth_server > > auth_http auth_host:auth_port/authserver; > > > > # mail server > > server { > > protocol smtp; > > listen 25; > > proxy on; > > xclient on; > > timeout 15; > > starttls on; > > ... other configs... > > } > > } > > > > With above config, we notice that nginx closes the connection after every > > auth request/response to Mail Authentication Server (auth_http > > auth_host:auth_port/authserver;) based on tcpdump analysis. We would like > > to make this connection persistent so that we could reuse connection for > > multiple auth requests. > > > > I looked at nginx mail auth module documentation ( > > > http://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#auth_http_header > > ) but I don't see any directive to make mail auth connection persistent. > > The auth_http module uses HTTP/1.0 and has no keepalive > connections support. > > If there are practical reasons why you want it to use keepalive, a > simple http proxy within the same nginx server will likely help. > > -- > 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 prabhashrathore at gmail.com Wed May 17 05:32:55 2017 From: prabhashrathore at gmail.com (Prabhash Rathore) Date: Wed, 17 May 2017 05:32:55 +0000 Subject: How to make nginx mail auth connection persistent? In-Reply-To: References: <20170516182609.GN55433@mdounin.ru> Message-ID: Hi Maxim, As per your suggestion to use Proxy server for auth_http directive in mail to enable keepalive connection, I recompiled my nginx with http and added following http configuration. http { server { server_name foo_server; location / { proxy_http_version 1.1; proxy_pass http://hostname:port/auth.php; } } } Now in mail directive, I am trying to refer this server from auth_http as follows but nginx does not recognize foo_server while start up. Could you please let me know how I can point "auth_http" to a proxy server configured in nginx config? mail { auth_http foo_server; # my server name from http config } Please let me know if this is not possible with just config chages then we will try to look at code change options. Thank you for your help in advance! Appreciate it! Prabhash Rathore On Tue, May 16, 2017 at 2:29 PM Prabhash Rathore wrote: > Hi Maxim, > > Thank you for your response! Our Mail backend system receives millions of > SMTP connection requests every day and for each connection request, we > need to establish new connection with auth server and then tear it down > which is an overhead on CPU and network. So we are looking on ways to use > HTTP1.1 persistent connection so that we can save on our resources by > reusing connections. I think it will be a nice feature to have in nginx? By > the way, is there a reason why nginx auth_http does not support http 1.1? > > Based on your suggestion, I tried following configuration but this did not > work. Nginx will not start complaining about unknown upstream and location > directives. > > upstream tss { > server host_name:port/smtp.php; > keepalive 32; > } > > location / { > proxy_http_version 1.1; > proxy_pass http://tss; > } > > mail { > # auth > auth_http tss; > } > > Could you please share sample proxy config which could be used to enable > keepalive for auth_http? > > Thanks! > Prabhash Rathore > > > On Tue, May 16, 2017 at 11:26 AM Maxim Dounin wrote: > >> Hello! >> >> On Tue, May 16, 2017 at 06:18:27PM +0000, Prabhash Rathore wrote: >> >> > We are using nginx 1.7.3 as a reverse proxy for our Mail SMTP service. >> For >> > authentication of each SMTP connection, we have configured nginx to >> connect >> > with a http based service for authentication. Here is a snippet of our >> > nginx config: >> > >> > mail { >> > # auth_server >> > auth_http auth_host:auth_port/authserver; >> > >> > # mail server >> > server { >> > protocol smtp; >> > listen 25; >> > proxy on; >> > xclient on; >> > timeout 15; >> > starttls on; >> > ... other configs... >> > } >> > } >> > >> > With above config, we notice that nginx closes the connection after >> every >> > auth request/response to Mail Authentication Server (auth_http >> > auth_host:auth_port/authserver;) based on tcpdump analysis. We would >> like >> > to make this connection persistent so that we could reuse connection for >> > multiple auth requests. >> > >> > I looked at nginx mail auth module documentation ( >> > >> http://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#auth_http_header >> > ) but I don't see any directive to make mail auth connection persistent. >> >> The auth_http module uses HTTP/1.0 and has no keepalive >> connections support. >> >> If there are practical reasons why you want it to use keepalive, a >> simple http proxy within the same nginx server will likely help. >> >> -- >> 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 mdounin at mdounin.ru Wed May 17 15:31:23 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 17 May 2017 18:31:23 +0300 Subject: How to make nginx mail auth connection persistent? In-Reply-To: References: <20170516182609.GN55433@mdounin.ru> Message-ID: <20170517153123.GO55433@mdounin.ru> Hello! On Wed, May 17, 2017 at 05:32:55AM +0000, Prabhash Rathore wrote: > Hi Maxim, > > As per your suggestion to use Proxy server for auth_http directive in mail > to enable keepalive connection, I recompiled my nginx with http and added > following http configuration. > > http { > server { > server_name foo_server; > location / { > proxy_http_version 1.1; > proxy_pass http://hostname:port/auth.php; > } > } > } > > Now in mail directive, I am trying to refer this server from auth_http as > follows but nginx does not recognize foo_server while start up. Could you > please let me know how I can point "auth_http" to a proxy server configured > in nginx config? > > mail { > auth_http foo_server; # my server name from http config > } > > Please let me know if this is not possible with just config chages then we > will try to look at code change options. You may want to ask for help in the nginx@ mailing list. This mailing list if for developers and certainly not appropriate for this kind of questions. You may also want to read nginx documentation as available here: http://nginx.org/en/docs/ Thank you. -- Maxim Dounin http://nginx.org/ From dnj0496 at gmail.com Thu May 18 00:53:40 2017 From: dnj0496 at gmail.com (Dk Jack) Date: Wed, 17 May 2017 17:53:40 -0700 Subject: releasing memory. Message-ID: Hi, In my module, I registered a NGX_HTTP_POST_READ_PHASE handler. When this handler is invoked, I allocate my module context and attach it to the request. I also allocate some other memory and save the pointers to that memory in my context. In the POST_READ_PHASE handler, I also register a cleanup handler to the request (r->cleanup; ngx_http_cleanup_t ). I assumed this is called before the request is freed. As I expected, my cleanup handler is getting called for most of the requests. However, in some cases it doesn't get called. This seems to happen mostly for the first request and if and only if the request is a very simple url like 'http://servername/' i.e. a simple request which tests server is up and running or not. If I add anything more to the uri-path, the cleanup handler gets called. Otherwise, it doesn't get called. Seems very strange. Could someone more knowledgeable comment on this behavior. Thanks. Dk. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pluknet at nginx.com Thu May 18 11:36:10 2017 From: pluknet at nginx.com (Sergey Kandaurov) Date: Thu, 18 May 2017 11:36:10 +0000 Subject: [nginx] Upstream: fixed u->headers_in.headers allocation error handling. Message-ID: details: http://hg.nginx.org/nginx/rev/08537eab4f23 branches: changeset: 7001:08537eab4f23 user: Sergey Kandaurov date: Thu May 18 14:17:00 2017 +0300 description: Upstream: fixed u->headers_in.headers allocation error handling. Previously, an allocation error resulted in uninitialized memory access when evaluating $upstream_http_ variables. On a related note, see r->headers_out.headers cleanup work in 0cdee26605f3. diffstat: src/http/modules/ngx_http_fastcgi_module.c | 3 +++ src/http/modules/ngx_http_proxy_module.c | 1 + src/http/modules/ngx_http_scgi_module.c | 1 + src/http/modules/ngx_http_uwsgi_module.c | 1 + 4 files changed, 6 insertions(+), 0 deletions(-) diffs (60 lines): diff -r d8e8ced78e77 -r 08537eab4f23 src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Mon May 15 20:09:44 2017 +0300 +++ b/src/http/modules/ngx_http_fastcgi_module.c Thu May 18 14:17:00 2017 +0300 @@ -1878,6 +1878,7 @@ ngx_http_fastcgi_process_header(ngx_http p = ngx_pnalloc(r->pool, size); if (p == NULL) { + h->hash = 0; return NGX_ERROR; } @@ -1900,6 +1901,7 @@ ngx_http_fastcgi_process_header(ngx_http ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "invalid header after joining " "FastCGI records"); + h->hash = 0; return NGX_ERROR; } @@ -1925,6 +1927,7 @@ ngx_http_fastcgi_process_header(ngx_http h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { + h->hash = 0; return NGX_ERROR; } diff -r d8e8ced78e77 -r 08537eab4f23 src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Mon May 15 20:09:44 2017 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Thu May 18 14:17:00 2017 +0300 @@ -1798,6 +1798,7 @@ ngx_http_proxy_process_header(ngx_http_r h->key.data = ngx_pnalloc(r->pool, h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { + h->hash = 0; return NGX_ERROR; } diff -r d8e8ced78e77 -r 08537eab4f23 src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c Mon May 15 20:09:44 2017 +0300 +++ b/src/http/modules/ngx_http_scgi_module.c Thu May 18 14:17:00 2017 +0300 @@ -1040,6 +1040,7 @@ ngx_http_scgi_process_header(ngx_http_re h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { + h->hash = 0; return NGX_ERROR; } diff -r d8e8ced78e77 -r 08537eab4f23 src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c Mon May 15 20:09:44 2017 +0300 +++ b/src/http/modules/ngx_http_uwsgi_module.c Thu May 18 14:17:00 2017 +0300 @@ -1244,6 +1244,7 @@ ngx_http_uwsgi_process_header(ngx_http_r h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { + h->hash = 0; return NGX_ERROR; } From mdounin at mdounin.ru Thu May 18 13:32:08 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 18 May 2017 16:32:08 +0300 Subject: releasing memory. In-Reply-To: References: Message-ID: <20170518133208.GR55433@mdounin.ru> Hello! On Wed, May 17, 2017 at 05:53:40PM -0700, Dk Jack wrote: > Hi, > In my module, I registered a NGX_HTTP_POST_READ_PHASE handler. When this > handler is invoked, I allocate my module context and attach it to the > request. I also allocate some other memory and save the pointers to that > memory in my context. In the POST_READ_PHASE handler, I also register a > cleanup handler to the request (r->cleanup; ngx_http_cleanup_t > ). I assumed this is > called before the request is freed. > > As I expected, my cleanup handler is getting called for most of the > requests. However, in some cases it doesn't get called. This seems to > happen mostly for the first request and if and only if the request is a > very simple url like 'http://servername/' i.e. a simple request which tests > server is up and running or not. If I add anything more to the uri-path, > the cleanup handler gets called. Otherwise, it doesn't get called. Seems > very strange. Could someone more knowledgeable comment on this behavior. > Thanks. HTTP cleanup handlers as added by ngx_http_cleanup_add() are only called on premature request termination via ngx_http_terminate_request(). They are to be used if your module does something that is expected to prevent normal request closing (for example, via increased r->count), but want nginx to be able to cancel this activity if it needs to terminate the request prematurely for some reason (usually due to an error). For example, upstream module installs a http cleanup handler when it connects to an upstream server, and aborts the connection if the cleanup handler is called. These handlers are not expected to be called on normal request completion, if nothing prevents normal close of a request. If your goal is to simply release resources when a request is freed, use a r->pool cleanup handler instead, as added by ngx_pool_cleanup_add(). -- Maxim Dounin http://nginx.org/ From xeioex at nginx.com Thu May 18 15:41:44 2017 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Thu, 18 May 2017 15:41:44 +0000 Subject: [nginx] Cache: ignore long locked entries during forced expire. Message-ID: details: http://hg.nginx.org/nginx/rev/ab199f0eb8e8 branches: changeset: 7002:ab199f0eb8e8 user: Dmitry Volyntsev date: Thu May 18 18:39:16 2017 +0300 description: Cache: ignore long locked entries during forced expire. Abnormally exited workers may leave locked cache entries, this can result in the cache size on disk exceeding max_size and shared memory exhaustion. This change mitigates the issue by ignoring locked entries during forced expire. It also increases the visibility of the problem by logging such entries. diffstat: src/http/ngx_http_file_cache.c | 57 ++++++++++++++++++++++++++++++++--------- 1 files changed, 44 insertions(+), 13 deletions(-) diffs (91 lines): diff -r 08537eab4f23 -r ab199f0eb8e8 src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c Thu May 18 14:17:00 2017 +0300 +++ b/src/http/ngx_http_file_cache.c Thu May 18 18:39:16 2017 +0300 @@ -1700,13 +1700,14 @@ ngx_http_file_cache_cleanup(void *data) static time_t ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache) { - u_char *name; + u_char *name, *p; size_t len; time_t wait; ngx_uint_t tries; ngx_path_t *path; - ngx_queue_t *q; + ngx_queue_t *q, *sentinel; ngx_http_file_cache_node_t *fcn; + u_char key[2 * NGX_HTTP_CACHE_KEY_LEN]; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache forced expire"); @@ -1723,13 +1724,21 @@ ngx_http_file_cache_forced_expire(ngx_ht wait = 10; tries = 20; + sentinel = NULL; ngx_shmtx_lock(&cache->shpool->mutex); - for (q = ngx_queue_last(&cache->sh->queue); - q != ngx_queue_sentinel(&cache->sh->queue); - q = ngx_queue_prev(q)) - { + for ( ;; ) { + if (ngx_queue_empty(&cache->sh->queue)) { + break; + } + + q = ngx_queue_last(&cache->sh->queue); + + if (q == sentinel) { + break; + } + fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, @@ -1740,15 +1749,37 @@ ngx_http_file_cache_forced_expire(ngx_ht if (fcn->count == 0) { ngx_http_file_cache_delete(cache, q, name); wait = 0; - - } else { - if (--tries) { - continue; - } - - wait = 1; + break; } + p = ngx_hex_dump(key, (u_char *) &fcn->node.key, + sizeof(ngx_rbtree_key_t)); + len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); + (void) ngx_hex_dump(p, fcn->key, len); + + /* + * abnormally exited workers may leave locked cache entries, + * and although it may be safe to remove them completely, + * we prefer to just move them to the top of the inactive queue + */ + + ngx_queue_remove(q); + fcn->expire = ngx_time() + cache->inactive; + ngx_queue_insert_head(&cache->sh->queue, &fcn->queue); + + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, + "ignore long locked inactive cache entry %*s, count:%d", + (size_t) 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); + + if (sentinel == NULL) { + sentinel = q; + } + + if (--tries) { + continue; + } + + wait = 1; break; } From 0 at lvht.net Thu May 18 17:12:29 2017 From: 0 at lvht.net (0 at lvht.net) Date: Fri, 19 May 2017 01:12:29 +0800 Subject: Http: make ngx_http_init_listening a public api In-Reply-To: References: Message-ID: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> Hello, Is there any maintainer who could review this patch? Thanks. > ? 2017?5?1??08:31?nginx-devel-bounces at nginx.org ??? > > # HG changeset patch > # User ??? <0 at lvht.net> > # Date 1493595577 -28800 > # Mon May 01 07:39:37 2017 +0800 > # Node ID 2ddd0894c1a6c7efe45310b874a5b4091b58bb81 > # Parent f38647c651a8d5c884b5aacc9f9a5b1af196309b > Http: make ngx_http_init_listening a public api > > Make this api public is a good convenience to allow other module > add listening port to http server dynamically. > > diff -r f38647c651a8 -r 2ddd0894c1a6 src/http/ngx_http.c > --- a/src/http/ngx_http.c Thu Apr 27 16:57:18 2017 +0300 > +++ b/src/http/ngx_http.c Mon May 01 07:39:37 2017 +0800 > @@ -55,8 +55,6 @@ static ngx_int_t ngx_http_cmp_conf_addrs > static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one, > const void *two); > > -static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, > - ngx_http_conf_port_t *port); > static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf, > ngx_http_conf_addr_t *addr); > static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport, > @@ -1623,7 +1621,7 @@ ngx_http_cmp_dns_wildcards(const void *o > } > > > -static ngx_int_t > +ngx_int_t > ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port) > { > ngx_uint_t i, last, bind_wildcard; > diff -r f38647c651a8 -r 2ddd0894c1a6 src/http/ngx_http.h > --- a/src/http/ngx_http.h Thu Apr 27 16:57:18 2017 +0300 > +++ b/src/http/ngx_http.h Mon May 01 07:39:37 2017 +0800 > @@ -80,6 +80,7 @@ ngx_int_t ngx_http_add_location(ngx_conf > ngx_http_core_loc_conf_t *clcf); > ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, > ngx_http_listen_opt_t *lsopt); > +ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port); > > > void ngx_http_init_connection(ngx_connection_t *c); > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From dnj0496 at gmail.com Thu May 18 17:23:18 2017 From: dnj0496 at gmail.com (Dk Jack) Date: Thu, 18 May 2017 10:23:18 -0700 Subject: releasing memory. In-Reply-To: <20170518133208.GR55433@mdounin.ru> References: <20170518133208.GR55433@mdounin.ru> Message-ID: <947B020F-E72C-4523-B9C3-5A4EA22ECF36@gmail.com> Thank you Maxim, I just want to release memory l've allocated. One more question, is the context memory automatically removed or is the module responsible for freeing it. > On May 18, 2017, at 6:32 AM, Maxim Dounin wrote: > > Hello! > >> On Wed, May 17, 2017 at 05:53:40PM -0700, Dk Jack wrote: >> >> Hi, >> In my module, I registered a NGX_HTTP_POST_READ_PHASE handler. When this >> handler is invoked, I allocate my module context and attach it to the >> request. I also allocate some other memory and save the pointers to that >> memory in my context. In the POST_READ_PHASE handler, I also register a >> cleanup handler to the request (r->cleanup; ngx_http_cleanup_t >> ). I assumed this is >> called before the request is freed. >> >> As I expected, my cleanup handler is getting called for most of the >> requests. However, in some cases it doesn't get called. This seems to >> happen mostly for the first request and if and only if the request is a >> very simple url like 'http://servername/' i.e. a simple request which tests >> server is up and running or not. If I add anything more to the uri-path, >> the cleanup handler gets called. Otherwise, it doesn't get called. Seems >> very strange. Could someone more knowledgeable comment on this behavior. >> Thanks. > > HTTP cleanup handlers as added by ngx_http_cleanup_add() are only > called on premature request termination via > ngx_http_terminate_request(). They are to be used if your module > does something that is expected to prevent normal request closing > (for example, via increased r->count), but want nginx to be able > to cancel this activity if it needs to terminate the request > prematurely for some reason (usually due to an error). For > example, upstream module installs a http cleanup handler when it > connects to an upstream server, and aborts the connection if the > cleanup handler is called. > > These handlers are not expected to be called on normal request > completion, if nothing prevents normal close of a request. > > If your goal is to simply release resources when a request is > freed, use a r->pool cleanup handler instead, as added by > ngx_pool_cleanup_add(). > > -- > Maxim Dounin > http://nginx.org/ > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From mdounin at mdounin.ru Thu May 18 17:50:38 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 18 May 2017 20:50:38 +0300 Subject: Http: make ngx_http_init_listening a public api In-Reply-To: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> References: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> Message-ID: <20170518175038.GU55433@mdounin.ru> Hello! On Fri, May 19, 2017 at 01:12:29AM +0800, 0 at lvht.net wrote: > Is there any maintainer who could review this patch? Thanks. I don't think this change is needed. Listening sockets are to be created using the "listen" directive of the core module, they are not expected to be added by other modules. If you think that this is needed, you may try to convince me and/or other developers by providing more details on how do you want to use it and why it is needed. > > > ? 2017?5?1??08:31?nginx-devel-bounces at nginx.org ??? > > > > # HG changeset patch > > # User ??? <0 at lvht.net> > > # Date 1493595577 -28800 > > # Mon May 01 07:39:37 2017 +0800 > > # Node ID 2ddd0894c1a6c7efe45310b874a5b4091b58bb81 > > # Parent f38647c651a8d5c884b5aacc9f9a5b1af196309b > > Http: make ngx_http_init_listening a public api > > > > Make this api public is a good convenience to allow other module > > add listening port to http server dynamically. > > > > diff -r f38647c651a8 -r 2ddd0894c1a6 src/http/ngx_http.c > > --- a/src/http/ngx_http.c Thu Apr 27 16:57:18 2017 +0300 > > +++ b/src/http/ngx_http.c Mon May 01 07:39:37 2017 +0800 > > @@ -55,8 +55,6 @@ static ngx_int_t ngx_http_cmp_conf_addrs > > static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one, > > const void *two); > > > > -static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, > > - ngx_http_conf_port_t *port); > > static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf, > > ngx_http_conf_addr_t *addr); > > static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport, > > @@ -1623,7 +1621,7 @@ ngx_http_cmp_dns_wildcards(const void *o > > } > > > > > > -static ngx_int_t > > +ngx_int_t > > ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port) > > { > > ngx_uint_t i, last, bind_wildcard; > > diff -r f38647c651a8 -r 2ddd0894c1a6 src/http/ngx_http.h > > --- a/src/http/ngx_http.h Thu Apr 27 16:57:18 2017 +0300 > > +++ b/src/http/ngx_http.h Mon May 01 07:39:37 2017 +0800 > > @@ -80,6 +80,7 @@ ngx_int_t ngx_http_add_location(ngx_conf > > ngx_http_core_loc_conf_t *clcf); > > ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, > > ngx_http_listen_opt_t *lsopt); > > +ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port); > > > > > > void ngx_http_init_connection(ngx_connection_t *c); > > _______________________________________________ > > 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 -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu May 18 17:57:09 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 18 May 2017 20:57:09 +0300 Subject: releasing memory. In-Reply-To: <947B020F-E72C-4523-B9C3-5A4EA22ECF36@gmail.com> References: <20170518133208.GR55433@mdounin.ru> <947B020F-E72C-4523-B9C3-5A4EA22ECF36@gmail.com> Message-ID: <20170518175708.GV55433@mdounin.ru> Hello! On Thu, May 18, 2017 at 10:23:18AM -0700, Dk Jack wrote: > I just want to release memory l've allocated. One more question, > is the context memory automatically removed or is the module > responsible for freeing it. Anything you allocate from request pool (r->pool) using ngx_p*alloc() functions is automatically freeded when the request pool is destroyed. If you allocate memory directly from OS, you are responsible to free it yourself (though this shouldn't happen except in very special cases). -- Maxim Dounin http://nginx.org/ From Nate.Karstens at garmin.com Thu May 18 18:22:41 2017 From: Nate.Karstens at garmin.com (Karstens, Nate) Date: Thu, 18 May 2017 18:22:41 +0000 Subject: [PATCH] Proxy: support configuration of socket buffer sizes In-Reply-To: <145451D4E6785E4DA4DFA353A58CB7B2015E152A53@OLAWPA-EXMB04.ad.garmin.com> References: <145451D4E6785E4DA4DFA353A58CB7B2015E152A53@OLAWPA-EXMB04.ad.garmin.com> Message-ID: <145451D4E6785E4DA4DFA353A58CB7B2015E158599@OLAWPA-EXMB04.ad.garmin.com> Greetings, I just wanted to follow up on this patch and make sure that the fraud detection notice or confidentiality notice added by my company wasn't precluding it from consideration. Thanks! Nate -----Original Message----- From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Karstens, Nate Sent: Sunday, April 30, 2017 12:19 PM To: nginx-devel at nginx.org Subject: [PATCH] Proxy: support configuration of socket buffer sizes [This sender failed our fraud detection checks and may not be who they appear to be. Learn about spoofing at http://aka.ms/LearnAboutSpoofing] # HG changeset patch # User Nate Karstens # Date 1493467011 18000 # Sat Apr 29 06:56:51 2017 -0500 # Node ID 1251a543804b17941b2c96b84bd1f4e58a37bc15 # Parent 8801ff7d58e1650c9d1abb50e09f5979e4f9ffbf Proxy: support configuration of socket buffer sizes Allows the size of the buffers used by the TCP sockets for HTTP proxy connections to be configured. The new configuration directives are: * proxy_socket_rcvbuf * proxy_socket_sndbuf These correspond with the SO_RCVBUF and SO_SNDBUF socket options, respectively. This is be useful in cases where the proxy processes received data slowly. Data was being buffered in three separate TCP buffers (nginx-from-client receive, nginx- to-proxy send, and proxy-from-nginx receive). The cumulative effect is that the client thinks it has sent all of the data, but times out waiting for a reply from the proxy, which cannot reply because it is still processing the data in its buffers. Signed-off-by: Nate Karstens diff -r 8801ff7d58e1 -r 1251a543804b src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c Tue Apr 25 23:39:13 2017 +0300 +++ b/src/event/ngx_event_connect.c Sat Apr 29 06:56:51 2017 -0500 @@ -73,6 +73,16 @@ } } + if (pc->sndbuf) { + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, + (const void *) &pc->sndbuf, sizeof(int)) == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(SO_SNDBUF) failed"); + goto failed; + } + } + if (ngx_nonblocking(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_nonblocking_n " failed"); diff -r 8801ff7d58e1 -r 1251a543804b src/event/ngx_event_connect.h --- a/src/event/ngx_event_connect.h Tue Apr 25 23:39:13 2017 +0300 +++ b/src/event/ngx_event_connect.h Sat Apr 29 06:56:51 2017 -0500 @@ -57,6 +57,7 @@ int type; int rcvbuf; + int sndbuf; ngx_log_t *log; diff -r 8801ff7d58e1 -r 1251a543804b src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Tue Apr 25 23:39:13 2017 +0300 +++ b/src/http/modules/ngx_http_proxy_module.c Sat Apr 29 06:56:51 2017 +++ -0500 @@ -90,6 +90,9 @@ ngx_uint_t headers_hash_max_size; ngx_uint_t headers_hash_bucket_size; + ngx_int_t rcvbuf; + ngx_int_t sndbuf; + #if (NGX_HTTP_SSL) ngx_uint_t ssl; ngx_uint_t ssl_protocols; @@ -629,6 +632,20 @@ offsetof(ngx_http_proxy_loc_conf_t, http_version), &ngx_http_proxy_http_version }, + { ngx_string("proxy_socket_rcvbuf"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, rcvbuf), + NULL }, + + { ngx_string("proxy_socket_sndbuf"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, sndbuf), + NULL }, + #if (NGX_HTTP_SSL) { ngx_string("proxy_ssl_session_reuse"), @@ -905,6 +922,13 @@ u->buffering = plcf->upstream.buffering; + if (plcf->rcvbuf != NGX_CONF_UNSET) { + u->peer.rcvbuf = plcf->rcvbuf; + } + if (plcf->sndbuf != NGX_CONF_UNSET) { + u->peer.sndbuf = plcf->sndbuf; + } + u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); if (u->pipe == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -2902,6 +2926,9 @@ conf->headers_hash_max_size = NGX_CONF_UNSET_UINT; conf->headers_hash_bucket_size = NGX_CONF_UNSET_UINT; + conf->rcvbuf = NGX_CONF_UNSET; + conf->sndbuf = NGX_CONF_UNSET; + ngx_str_set(&conf->upstream.module, "proxy"); return conf; @@ -3297,6 +3324,12 @@ ngx_conf_merge_uint_value(conf->headers_hash_bucket_size, prev->headers_hash_bucket_size, 64); + ngx_conf_merge_value(conf->rcvbuf, + prev->rcvbuf, NGX_CONF_UNSET); + + ngx_conf_merge_value(conf->sndbuf, + prev->sndbuf, NGX_CONF_UNSET); + conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size, ngx_cacheline_size); ________________________________ CONFIDENTIALITY NOTICE: This email and any attachments are for the sole use of the intended recipient(s) and contain information that may be Garmin confidential and/or Garmin legally privileged. If you have received this email in error, please notify the sender by reply email and delete the message. Any disclosure, copying, distribution or use of this communication (including attachments) by someone other than the intended recipient is prohibited. Thank you. _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From 0 at lvht.net Thu May 18 19:04:43 2017 From: 0 at lvht.net (0 at lvht.net) Date: Fri, 19 May 2017 03:04:43 +0800 Subject: Http: make ngx_http_init_listening a public api In-Reply-To: <20170518175038.GU55433@mdounin.ru> References: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> <20170518175038.GU55433@mdounin.ru> Message-ID: <8718AAE9-65EB-4F66-805C-9F8DCC7C4113> Thank you for your reply. As a client oriented proxy server, nginx will boot several worker process to listen on the same port. If a tcp connection is initiated, this connection will be processed by one worker. This model is simple yet efficient. However this model makes it impossible to let nginx work as a standalone server of some protocols, for example, websocket. Please let me assume it make sense to make nginx work as a standalone websock server. The problem we will face is that we cannot send message to client. Because when the client initial tcp connection, the connection will be processed by one worker uncertainly. If we want push message to one client, we must find the worker processing this client connection. I have a simple idea. If we add an additional unique listen port for each http server directive before worker process do the event loop dynamically, we could use the added port to send message to client. As the listen directive is processed in the master process, it does make any help. Talk is cheap. I just make a prototype at https://github.com/lvht/nginx-websocket-module This model makes nginx as a standalone websocket server, and business logic free as soon as possible. The idea of adding unique listening port dynamically is a practical solution for any protocol which need to send data to message initially, websocket, sse, http poll, etc.. It is also impossible to add new listening port to an http server directive dynamically in the websocket model, but it will be a huge burden to sync this logic to the http model. So I propose nginx to open this api. Please forgive me for my poor English. Thanks. > On 19 May 2017, at 01:50, Maxim Dounin wrote: > > Hello! > >> On Fri, May 19, 2017 at 01:12:29AM +0800, 0 at lvht.net wrote: >> >> Is there any maintainer who could review this patch? Thanks. > > I don't think this change is needed. Listening sockets are to be > created using the "listen" directive of the core module, they are > not expected to be added by other modules. > > If you think that this is needed, you may try to convince me > and/or other developers by providing more details on how do you > want to use it and why it is needed. > >> >>> ? 2017?5?1??08:31?nginx-devel-bounces at nginx.org ??? >>> >>> # HG changeset patch >>> # User ??? <0 at lvht.net> >>> # Date 1493595577 -28800 >>> # Mon May 01 07:39:37 2017 +0800 >>> # Node ID 2ddd0894c1a6c7efe45310b874a5b4091b58bb81 >>> # Parent f38647c651a8d5c884b5aacc9f9a5b1af196309b >>> Http: make ngx_http_init_listening a public api >>> >>> Make this api public is a good convenience to allow other module >>> add listening port to http server dynamically. >>> >>> diff -r f38647c651a8 -r 2ddd0894c1a6 src/http/ngx_http.c >>> --- a/src/http/ngx_http.c Thu Apr 27 16:57:18 2017 +0300 >>> +++ b/src/http/ngx_http.c Mon May 01 07:39:37 2017 +0800 >>> @@ -55,8 +55,6 @@ static ngx_int_t ngx_http_cmp_conf_addrs >>> static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one, >>> const void *two); >>> >>> -static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, >>> - ngx_http_conf_port_t *port); >>> static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf, >>> ngx_http_conf_addr_t *addr); >>> static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport, >>> @@ -1623,7 +1621,7 @@ ngx_http_cmp_dns_wildcards(const void *o >>> } >>> >>> >>> -static ngx_int_t >>> +ngx_int_t >>> ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port) >>> { >>> ngx_uint_t i, last, bind_wildcard; >>> diff -r f38647c651a8 -r 2ddd0894c1a6 src/http/ngx_http.h >>> --- a/src/http/ngx_http.h Thu Apr 27 16:57:18 2017 +0300 >>> +++ b/src/http/ngx_http.h Mon May 01 07:39:37 2017 +0800 >>> @@ -80,6 +80,7 @@ ngx_int_t ngx_http_add_location(ngx_conf >>> ngx_http_core_loc_conf_t *clcf); >>> ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, >>> ngx_http_listen_opt_t *lsopt); >>> +ngx_int_t ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port); >>> >>> >>> void ngx_http_init_connection(ngx_connection_t *c); >>> _______________________________________________ >>> 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 > > -- > 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 dnj0496 at gmail.com Thu May 18 22:06:32 2017 From: dnj0496 at gmail.com (Dk Jack) Date: Thu, 18 May 2017 15:06:32 -0700 Subject: releasing memory. In-Reply-To: <20170518175708.GV55433@mdounin.ru> References: <20170518133208.GR55433@mdounin.ru> <947B020F-E72C-4523-B9C3-5A4EA22ECF36@gmail.com> <20170518175708.GV55433@mdounin.ru> Message-ID: My module has c++ code which instantiates a class. I am driving most of my c++ from one ptr which I am saving in the context. I tried changing my code to use pool cleanup, it behaving worse than request->cleanup. Of the four requests I send, the cleanup handler is only getting called for two. I did a little more digging into the request->cleanup issue. It looks like, for the case where I thought my cleanup handler wasn't getting called, it was actually getting called. In my handler I was trying to retrieve my module context (ngx_http_get_module_ctx). I could not retrieve the module context in the failure case. I allocated my context from r->connection->pool. I suspect, in the failure case the contexts are getting freed before the clean up callbacks are complete. On Thu, May 18, 2017 at 10:57 AM, Maxim Dounin wrote: > Hello! > > On Thu, May 18, 2017 at 10:23:18AM -0700, Dk Jack wrote: > > > I just want to release memory l've allocated. One more question, > > is the context memory automatically removed or is the module > > responsible for freeing it. > > Anything you allocate from request pool (r->pool) using > ngx_p*alloc() functions is automatically freeded when the request > pool is destroyed. If you allocate memory directly from OS, you > are responsible to free it yourself (though this shouldn't happen > except in very special cases). > > -- > 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 mdounin at mdounin.ru Fri May 19 16:25:19 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 19 May 2017 19:25:19 +0300 Subject: [PATCH 1 of 2] SSI: implemented "fsize" SSI command In-Reply-To: <0d6c509169a32624cce4.1493633396@oak.local> References: <0d6c509169a32624cce4.1493633396@oak.local> Message-ID: <20170519162519.GY55433@mdounin.ru> Hello! On Mon, May 01, 2017 at 01:09:56PM +0300, Matwey V. Kornilov wrote: > # HG changeset patch > # User Matwey V. Kornilov > # Date 1492936703 -10800 > # Sun Apr 23 11:38:23 2017 +0300 > # Branch fsize > # Node ID 0d6c509169a32624cce431f2469b10b4f961510e > # Parent 5116cfea1e9a84be678af10e0ff1f1fce9b00cfb > SSI: implemented "fsize" SSI command. In the previous review I've expressed concerns that this uses body output in a subrequest with r->header_only set, see http://mailman.nginx.org/pipermail/nginx-devel/2017-April/009814.html. Do you have anything to comment on this? [...] > +static ngx_int_t > +ngx_http_ssi_fsize_output(ngx_http_request_t *r, void *data, ngx_int_t rc) > +{ > + off_t length; > + u_char scale; > + unsigned exact_size; > + ngx_buf_t *b; > + ngx_int_t size; > + ngx_chain_t *out; > + ngx_http_ssi_ctx_t *ctx; Style: as I already wrote during previous review, there should be at least two spaces between variable type and the variable. > + > + ctx = data; > + exact_size = ctx->exact_size; Note that this approach doesn't work if there is more than one config command, as subrequests are executed in parallel and thus this uses latest config. For example, fsize sizefmt=bytes: fsize sizefmt=abbrev: outputs fsize sizefmt=bytes: 8M fsize sizefmt=abbrev: 8M and this certainly looks wrong (and works fine with Apache). This might be another argument to make it blocking instead, similar to wait="yes" in "include" command. In the patch below I've tried to resolve this by passing current exact_size to the subrequest directly, but it still fails to use correct error message if it is redefined more than once in a similar manner. > + > + if (r->request_output) { > + return rc; > + } > + > + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, > + "ssi fsize output: \"%V?%V\"", &r->uri, &r->args); > + > + b = ngx_create_temp_buf(r->pool, NGX_OFF_T_LEN + 2); > + if (b == NULL) { > + return NGX_ERROR; > + } > + > + length = r->headers_out.content_length_n; > + > + if (!exact_size && length > 1024 * 1024 * 1024 - 1) { > + size = (ngx_int_t) (length / (1024 * 1024 * 1024)); > + if ((length % (1024 * 1024 * 1024)) > + > (1024 * 1024 * 1024 / 2 - 1)) Style: there is no need to break the line here. Corresponding line in the autoindex module is broken down because it doesn't fit into 80 chars, but this is not the case here. > + { > + size++; > + } > + scale = 'G'; > + > + } else if (!exact_size && length > 1024 * 1024 - 1) { > + size = (ngx_int_t) (length / (1024 * 1024)); > + if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) { > + size++; > + } > + scale = 'M'; > + > + } else if (!exact_size && length > 9999) { > + size = (ngx_int_t) (length / 1024); > + if (length % 1024 > 511) { > + size++; > + } > + scale = 'K'; > + > + } else { > + size = (ngx_int_t) length; > + scale = '\0'; > + } In this code you test "exact_size" flag in each "if", and then fallback to the last "else". IMHO, this complicates understanding the code compared to separate handling of exact_size case as in the autoindex module. And, more importantly, this breaks prerequisites on using ngx_int_t type for "size", leading to incorrect results for files larger than 2G on 32-bit platforms when using exact_size. > + > + if (length < 0) { > + b->pos = ctx->errmsg.data; > + b->last = ctx->errmsg.data + ctx->errmsg.len; It is not clear why size/scale where at all calculated for this case. It might also worth to exclude various non-200 status codes, as currently referring to a non-existing file on a backend results in a size of the error page returned. Also, various strange things can happen when trying to output anything if "rc" is NGX_ERROR. See, for example, ngx_http_ssi_stub_output(), which doesn't try to do anything if "rc" is NGX_ERROR, or if r->connection->error is set. > + > + } else if (scale) { > + b->last = ngx_sprintf(b->last, "%6i%c", size, scale); > + > + } else { > + b->last = ngx_sprintf(b->last, " %6i", size); It is not clear why you are using the leading space here, as well as "%6i" format. This is something important in the autoindex module that uses fixed-width table, but I don't think this is expected in output of the "fsize" SSI command. > + } > + > + out = ngx_alloc_chain_link(r->pool); > + if (out == NULL) { > + return NGX_ERROR; > + } > + > + out->buf = b; > + out->next = NULL; > + > + return ngx_http_output_filter(r, out); > +} > + > + > +static ngx_int_t > ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, > ngx_str_t **params) > { > @@ -2400,6 +2561,27 @@ > ctx->errmsg = *value; > } > > + value = params[NGX_HTTP_SSI_CONFIG_SIZEFMT]; > + > + if (value) { > + if (value->len == 5 > + && ngx_strncasecmp(value->data, (u_char *) "bytes", 5) == 0) > + { > + ctx->exact_size = 1; > + > + } else if (value->len == 6 > + && ngx_strncasecmp(value->data, (u_char *) "abbrev", 6) == 0) > + { > + ctx->exact_size = 0; > + > + } else { > + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, > + "unknown size format \"%V\" " > + "in \"config\" SSI command", value); Style, continuation lines should be aligned with the first function argument: ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "unknown size format \"%V\" " "in \"config\" SSI command", value); > + return NGX_HTTP_SSI_ERROR; > + } > + } > + > return NGX_OK; > } > > diff -r 5116cfea1e9a -r 0d6c509169a3 src/http/modules/ngx_http_ssi_filter_module.h > --- a/src/http/modules/ngx_http_ssi_filter_module.h Thu Apr 20 18:26:38 2017 +0300 > +++ b/src/http/modules/ngx_http_ssi_filter_module.h Sun Apr 23 11:38:23 2017 +0300 > @@ -76,6 +76,7 @@ > unsigned block:1; > unsigned output:1; > unsigned output_chosen:1; > + unsigned exact_size:1; > > ngx_http_request_t *wait; > void *value_buf; Here is a patch which tries to address some of the above concerns: diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -2310,7 +2310,7 @@ ngx_http_ssi_fsize(ngx_http_request_t *r } psr->handler = ngx_http_ssi_fsize_output; - psr->data = ctx; + psr->data = (void *) ctx->exact_size; if (ngx_http_subrequest(r, uri, &args, &sr, psr, flags) != NGX_OK) { return NGX_HTTP_SSI_ERROR; @@ -2325,68 +2325,74 @@ ngx_http_ssi_fsize(ngx_http_request_t *r static ngx_int_t ngx_http_ssi_fsize_output(ngx_http_request_t *r, void *data, ngx_int_t rc) { - off_t length; - u_char scale; - unsigned exact_size; - ngx_buf_t *b; - ngx_int_t size; - ngx_chain_t *out; - ngx_http_ssi_ctx_t *ctx; - - ctx = data; - exact_size = ctx->exact_size; - - if (r->request_output) { + off_t length; + u_char scale; + ngx_buf_t *b; + ngx_int_t size; + ngx_uint_t exact_size; + ngx_chain_t *out; + ngx_http_ssi_ctx_t *ctx; + + if (rc == NGX_ERROR || r->connection->error || r->request_output) { return rc; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ssi fsize output: \"%V?%V\"", &r->uri, &r->args); + exact_size = (ngx_uint_t) data; + ctx = ngx_http_get_module_ctx(r->parent, ngx_http_ssi_filter_module); + b = ngx_create_temp_buf(r->pool, NGX_OFF_T_LEN + 2); if (b == NULL) { return NGX_ERROR; } - length = r->headers_out.content_length_n; - - if (!exact_size && length > 1024 * 1024 * 1024 - 1) { - size = (ngx_int_t) (length / (1024 * 1024 * 1024)); - if ((length % (1024 * 1024 * 1024)) - > (1024 * 1024 * 1024 / 2 - 1)) - { - size++; - } - scale = 'G'; - - } else if (!exact_size && length > 1024 * 1024 - 1) { - size = (ngx_int_t) (length / (1024 * 1024)); - if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) { - size++; - } - scale = 'M'; - - } else if (!exact_size && length > 9999) { - size = (ngx_int_t) (length / 1024); - if (length % 1024 > 511) { - size++; - } - scale = 'K'; + if (r->headers_out.status != NGX_HTTP_OK + || r->headers_out.content_length_n < 0) + { + b->pos = ctx->errmsg.data; + b->last = ctx->errmsg.data + ctx->errmsg.len; + + } else if (exact_size) { + b->last = ngx_sprintf(b->last, "%O", r->headers_out.content_length_n); } else { - size = (ngx_int_t) length; - scale = '\0'; - } - - if (length < 0) { - b->pos = ctx->errmsg.data; - b->last = ctx->errmsg.data + ctx->errmsg.len; - - } else if (scale) { - b->last = ngx_sprintf(b->last, "%6i%c", size, scale); - - } else { - b->last = ngx_sprintf(b->last, " %6i", size); + length = r->headers_out.content_length_n; + + if (length > 1024 * 1024 * 1024 - 1) { + size = (ngx_int_t) (length / (1024 * 1024 * 1024)); + if ((length % (1024 * 1024 * 1024)) > (1024 * 1024 * 1024 / 2 - 1)) + { + size++; + } + scale = 'G'; + + } else if (length > 1024 * 1024 - 1) { + size = (ngx_int_t) (length / (1024 * 1024)); + if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) { + size++; + } + scale = 'M'; + + } else if (length > 9999) { + size = (ngx_int_t) (length / 1024); + if (length % 1024 > 511) { + size++; + } + scale = 'K'; + + } else { + size = (ngx_int_t) length; + scale = '\0'; + } + + if (scale) { + b->last = ngx_sprintf(b->last, "%i%c", size, scale); + + } else { + b->last = ngx_sprintf(b->last, "%i", size); + } } out = ngx_alloc_chain_link(r->pool); @@ -2576,8 +2582,8 @@ ngx_http_ssi_config(ngx_http_request_t * } else { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "unknown size format \"%V\" " - "in \"config\" SSI command", value); + "unknown size format \"%V\" " + "in \"config\" SSI command", value); return NGX_HTTP_SSI_ERROR; } } -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Fri May 19 17:55:54 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 19 May 2017 20:55:54 +0300 Subject: Http: make ngx_http_init_listening a public api In-Reply-To: <8718AAE9-65EB-4F66-805C-9F8DCC7C4113> References: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> <20170518175038.GU55433@mdounin.ru> <8718AAE9-65EB-4F66-805C-9F8DCC7C4113> Message-ID: <20170519175554.GA55433@mdounin.ru> Hello! On Fri, May 19, 2017 at 03:04:43AM +0800, 0 at lvht.net wrote: > Thank you for your reply. > > As a client oriented proxy server, nginx will boot several > worker process to listen on the same port. If a tcp connection > is initiated, this connection will be processed by one worker. > This model is simple yet efficient. However this model makes it > impossible to let nginx work as a standalone server of some > protocols, for example, websocket. > > Please let me assume it make sense to make nginx work as a > standalone websock server. The problem we will face is that we > cannot send message to client. Because when the client initial > tcp connection, the connection will be processed by one worker > uncertainly. If we want push message to one client, we must find > the worker processing this client connection. > > I have a simple idea. If we add an additional unique listen port > for each http server directive before worker process do the > event loop dynamically, we could use the added port to send > message to client. As the listen directive is processed in the > master process, it does make any help. > > Talk is cheap. I just make a prototype at > https://github.com/lvht/nginx-websocket-module > > This model makes nginx as a standalone websocket server, and > business logic free as soon as possible. > > The idea of adding unique listening port dynamically is a > practical solution for any protocol which need to send data to > message initially, websocket, sse, http poll, etc.. > > It is also impossible to add new listening port to an http > server directive dynamically in the websocket model, but it will > be a huge burden to sync this logic to the http model. So I > propose nginx to open this api. Thank you for the detailed explanation. So, you are trying to introduce per-process listening sockets in order to be able to communicate with a particular worker process. This is highly unlikely to work properly without deep integration with nginx itself, and/or will be broken by trivial unrelated changes in nginx. So the answer is still negative. If you want to try to address the problem properly, consider the following approaches: - create listening sockets yourself, and handle connections in your module; - introduce per-process listining sockets in nginx core; likely there will many obscure problems though, including things like what to do on graceful shutdown; - use interprocess communication instead - for example, nginx has shared memory available to modules (there are also channels to pass messages between processes, but these are not currently available to modules). You may also want to look into Nchan module by Leo Ponomarev, it is expected to contain some solutions to the problems you are working on. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Fri May 19 18:21:11 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 19 May 2017 21:21:11 +0300 Subject: [PATCH] Proxy: support configuration of socket buffer sizes In-Reply-To: <145451D4E6785E4DA4DFA353A58CB7B2015E158599@OLAWPA-EXMB04.ad.garmin.com> References: <145451D4E6785E4DA4DFA353A58CB7B2015E152A53@OLAWPA-EXMB04.ad.garmin.com> <145451D4E6785E4DA4DFA353A58CB7B2015E158599@OLAWPA-EXMB04.ad.garmin.com> Message-ID: <20170519182111.GB55433@mdounin.ru> Hello! On Thu, May 18, 2017 at 06:22:41PM +0000, Karstens, Nate wrote: > I just wanted to follow up on this patch and make sure that the > fraud detection notice or confidentiality notice added by my > company wasn't precluding it from consideration. No, it wasn't. And the fraud detection notice seems to be added on your incoming mail, the mailing list copy don't contain anything like this, see http://nginx.org/pipermail/nginx-devel/2017-April/009876.html. Avoiding confidentiality noticies on public mailing lists might be a good idea though. [...] > # HG changeset patch > # User Nate Karstens # Date > 1493467011 18000 > # Sat Apr 29 06:56:51 2017 -0500 > # Node ID 1251a543804b17941b2c96b84bd1f4e58a37bc15 > # Parent 8801ff7d58e1650c9d1abb50e09f5979e4f9ffbf > Proxy: support configuration of socket buffer sizes > > Allows the size of the buffers used by the TCP sockets for HTTP > proxy connections to be configured. The new configuration > directives are: > > * proxy_socket_rcvbuf > * proxy_socket_sndbuf > > These correspond with the SO_RCVBUF and SO_SNDBUF socket > options, respectively. > > This is be useful in cases where the proxy processes received > data slowly. Data was being buffered in three separate TCP > buffers (nginx-from-client receive, nginx- to-proxy send, and > proxy-from-nginx receive). The cumulative effect is that the > client thinks it has sent all of the data, but times out waiting > for a reply from the proxy, which cannot reply because it is > still processing the data in its buffers. In practice, we've never seen cases when default socket buffer sizes on backend connections are not appopriate, and/or tuning system default is not sufficient. So even, as you can see from the code, nginx is able to tune SO_RCVBUF in ngx_event_connect_peer(), this was never exposed to configuration. This may be related to the fact that HTTP in general doesn't really depends on particular parts of a request being buffered, and nginx does not use pipelining in requests. Could you please elaborate more on the use case where you see the problem described, and why tuning system defaults is not sufficient in your case? -- Maxim Dounin http://nginx.org/ From 0 at lvht.net Sat May 20 02:58:03 2017 From: 0 at lvht.net (0 at lvht.net) Date: Sat, 20 May 2017 10:58:03 +0800 Subject: Http: make ngx_http_init_listening a public api In-Reply-To: <20170519175554.GA55433@mdounin.ru> References: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> <20170518175038.GU55433@mdounin.ru> <8718AAE9-65EB-4F66-805C-9F8DCC7C4113> <20170519175554.GA55433@mdounin.ru> Message-ID: <23B06B60-B0D8-4F9F-9210-BBD692864D43> > On 20 May 2017, at 01:56, Maxim Dounin wrote: > > Hello! > >> On Fri, May 19, 2017 at 03:04:43AM +0800, 0 at lvht.net wrote: >> >> Thank you for your reply. >> >> As a client oriented proxy server, nginx will boot several >> worker process to listen on the same port. If a tcp connection >> is initiated, this connection will be processed by one worker. >> This model is simple yet efficient. However this model makes it >> impossible to let nginx work as a standalone server of some >> protocols, for example, websocket. >> >> Please let me assume it make sense to make nginx work as a >> standalone websock server. The problem we will face is that we >> cannot send message to client. Because when the client initial >> tcp connection, the connection will be processed by one worker >> uncertainly. If we want push message to one client, we must find >> the worker processing this client connection. >> >> I have a simple idea. If we add an additional unique listen port >> for each http server directive before worker process do the >> event loop dynamically, we could use the added port to send >> message to client. As the listen directive is processed in the >> master process, it does make any help. >> >> Talk is cheap. I just make a prototype at >> https://github.com/lvht/nginx-websocket-module >> >> This model makes nginx as a standalone websocket server, and >> business logic free as soon as possible. >> >> The idea of adding unique listening port dynamically is a >> practical solution for any protocol which need to send data to >> message initially, websocket, sse, http poll, etc.. >> >> It is also impossible to add new listening port to an http >> server directive dynamically in the websocket model, but it will >> be a huge burden to sync this logic to the http model. So I >> propose nginx to open this api. > > Thank you for the detailed explanation. > > So, you are trying to introduce per-process listening sockets in > order to be able to communicate with a particular worker process. > > This is highly unlikely to work properly without deep integration > with nginx itself, and/or will be broken by trivial unrelated > changes in nginx. So the answer is still negative. > > If you want to try to address the problem properly, consider the > following approaches: > > - create listening sockets yourself, and handle connections in > your module; > > - introduce per-process listining sockets in nginx core; likely > there will many obscure problems though, including things like > what to do on graceful shutdown; > > - use interprocess communication instead - for example, nginx has > shared memory available to modules (there are also channels to > pass messages between processes, but these are not currently > available to modules). > > You may also want to look into Nchan module by Leo Ponomarev, it > is expected to contain some solutions to the problems you are > working on. > > -- > Maxim Dounin > http://nginx.org/ > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From 0 at lvht.net Sat May 20 06:33:34 2017 From: 0 at lvht.net (=?utf-8?B?5ZCV5rW35rab?=) Date: Sat, 20 May 2017 14:33:34 +0800 Subject: Http: make ngx_http_init_listening a public api In-Reply-To: <20170519175554.GA55433@mdounin.ru> References: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> <20170518175038.GU55433@mdounin.ru> <8718AAE9-65EB-4F66-805C-9F8DCC7C4113> <20170519175554.GA55433@mdounin.ru> Message-ID: Hello! What I still want to point out is that the job of the ngx_http_init_listening is not bind and listen on some certain tcp port waiting for incoming http request, but init the structs about listening adders and ports, associate them with http server and push the listening struct into the cycle->listening list. And all the process has been finished before the event module startup. As I am trying to introduce pre-process http listening sockets, I have to create listening socket during the worker process startup. And I have to init all the structs about listening address and port, and associate them with corresponding http server, and push the listening struct into the cycle->listening list. So when the push http request is coming, nginx will choose the right http server to handle the request. All the work has been done well by the nix_http_init_listening api.So I proposed to open this api. If I do all these job on my own module, I would reinvent a new nix_http_init_listening api. Introducing pre-process listening socket support in nginx core is cool, but more completed. And it is both hard to be implemented and to be merged. The share-memory solution will make the work model more complex and less efficient. I would like to separate worker process as much as possible. So I would like to choose the first approach you offered. It is more simple and clear. The nchan module seems awesome. And I will make more research on it. Thanks. > On 20 May 2017, at 01:55, Maxim Dounin wrote: > > Hello! > > On Fri, May 19, 2017 at 03:04:43AM +0800, 0 at lvht.net wrote: > >> Thank you for your reply. >> >> As a client oriented proxy server, nginx will boot several >> worker process to listen on the same port. If a tcp connection >> is initiated, this connection will be processed by one worker. >> This model is simple yet efficient. However this model makes it >> impossible to let nginx work as a standalone server of some >> protocols, for example, websocket. >> >> Please let me assume it make sense to make nginx work as a >> standalone websock server. The problem we will face is that we >> cannot send message to client. Because when the client initial >> tcp connection, the connection will be processed by one worker >> uncertainly. If we want push message to one client, we must find >> the worker processing this client connection. >> >> I have a simple idea. If we add an additional unique listen port >> for each http server directive before worker process do the >> event loop dynamically, we could use the added port to send >> message to client. As the listen directive is processed in the >> master process, it does make any help. >> >> Talk is cheap. I just make a prototype at >> https://github.com/lvht/nginx-websocket-module >> >> This model makes nginx as a standalone websocket server, and >> business logic free as soon as possible. >> >> The idea of adding unique listening port dynamically is a >> practical solution for any protocol which need to send data to >> message initially, websocket, sse, http poll, etc.. >> >> It is also impossible to add new listening port to an http >> server directive dynamically in the websocket model, but it will >> be a huge burden to sync this logic to the http model. So I >> propose nginx to open this api. > > Thank you for the detailed explanation. > > So, you are trying to introduce per-process listening sockets in > order to be able to communicate with a particular worker process. > > This is highly unlikely to work properly without deep integration > with nginx itself, and/or will be broken by trivial unrelated > changes in nginx. So the answer is still negative. > > If you want to try to address the problem properly, consider the > following approaches: > > - create listening sockets yourself, and handle connections in > your module; > > - introduce per-process listining sockets in nginx core; likely > there will many obscure problems though, including things like > what to do on graceful shutdown; > > - use interprocess communication instead - for example, nginx has > shared memory available to modules (there are also channels to > pass messages between processes, but these are not currently > available to modules). > > You may also want to look into Nchan module by Leo Ponomarev, it > is expected to contain some solutions to the problems you are > working on. > > -- > 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 hucong.c at foxmail.com Sun May 21 17:17:40 2017 From: hucong.c at foxmail.com (=?utf-8?B?6IOh6IGqIChodWNjKQ==?=) Date: Mon, 22 May 2017 01:17:40 +0800 Subject: Http: make ngx_http_init_listening a public api In-Reply-To: <20170519175554.GA55433@mdounin.ru> References: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> <20170518175038.GU55433@mdounin.ru> <8718AAE9-65EB-4F66-805C-9F8DCC7C4113> <20170519175554.GA55433@mdounin.ru> Message-ID: Hi, On Saturday, May 20, 2017 1:55 AM +0300, Maxim Dounin wrote: >On Fri, May 19, 2017 at 03:04:43AM +0800, 0 at lvht.net wrote: > >> Thank you for your reply. >> ******** >> Please let me assume it make sense to make nginx work as a >> standalone websock server. The problem we will face is that we >> cannot send message to client. Because when the client initial >> tcp connection, the connection will be processed by one worker >> uncertainly. If we want push message to one client, we must find >> the worker processing this client connection. >> ********* >> It is also impossible to add new listening port to an http >> server directive dynamically in the websocket model, but it will >> be a huge burden to sync this logic to the http model. So I >> propose nginx to open this api. > >Thank you for the detailed explanation. > >So, you are trying to introduce per-process listening sockets in >order to be able to communicate with a particular worker process. > >This is highly unlikely to work properly without deep integration >with nginx itself, and/or will be broken by trivial unrelated >changes in nginx. So the answer is still negative. > >If you want to try to address the problem properly, consider the >following approaches: > >- create listening sockets yourself, and handle connections in > your module; > >- introduce per-process listining sockets in nginx core; likely > there will many obscure problems though, including things like > what to do on graceful shutdown; > >- use interprocess communication instead - for example, nginx has > shared memory available to modules (there are also channels to > pass messages between processes, but these are not currently > available to modules). It is necessary to introduce per-process listening sockets in nginx core. Laster year, I have done most of the work, when I found it is hard to establish the connection to push data to another process in ngx_rtmp_auto_push_moudle. The problem can be solved by introduce a flag aloneport in ngx_listening_t and work with ls->worker. The configuration is listen ** [aloneport=ngx_worder]. And as far as I know, there is an obscure problem which is what to do on reload when new worker_processes number is less than the no-update ngx_worker of aloneport. As for the problem about what to do on graceful shutdown, I still don`t get it. Besides, I hope that arut will provide some ideas. Another problem/idea found in ngx_rtmp_module, it is also necessary to introduce a config options like NGX_3RD_CORE_MODULES (or other way or options) to ensure the 3rd party CORE modules is behind ngx_events_module. It is going to solve some obscure problems where the solution in ngx_rtmp_module is unfriendly and incomprehensible. If you guys also think it is needed, I will provide the patch of aloneport once time permits. Best wishes -hucc _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From fooinha at gmail.com Sun May 21 17:52:48 2017 From: fooinha at gmail.com (Paulo Pacheco) Date: Sun, 21 May 2017 18:52:48 +0100 Subject: [njs] Lexer support for hexadecimal literal values. Message-ID: # HG changeset patch # User Paulo Pacheco # Date 1495388206 0 # Sun May 21 17:36:46 2017 +0000 # Node ID 22db6b6a3a0eebff8453fb22035628410c05c5c8 # Parent 96fda9957427e1ea78d0096b019a3f3183db7346 [njs] Lexer support for hexadecimal literal values. diff -r 96fda9957427 -r 22db6b6a3a0e njs/njs_lexer.c --- a/njs/njs_lexer.c Wed Apr 19 17:48:56 2017 +0300 +++ b/njs/njs_lexer.c Sun May 21 17:36:46 2017 +0000 @@ -19,7 +19,7 @@ #include #include #include - +#include typedef struct njs_lexer_multi_s njs_lexer_multi_t; @@ -539,10 +539,28 @@ { u_char c, *p; double num, frac, scale; + char *endptr; /* TODO: "1e2" */ p = lexer->start; + + /* Hexadecimal literal values */ + if ( (lexer->end - lexer->start) > 2 + && (*p == 'x' || *p == 'X') + && (lexer->prev_token > 0 + || ((lexer->start - 1) == lexer->text.start) + ) + && (*(p-1) == '0')) { + + lexer->number = strtod((const char *) p-1, &endptr); + if ((u_char *) endptr <= lexer->end) { + lexer->start = (u_char *) endptr; + return NJS_TOKEN_NUMBER; + } + lexer->number = 0; + } + c = p[-1]; /* Values below '0' become >= 208. */ diff -r 96fda9957427 -r 22db6b6a3a0e njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Apr 19 17:48:56 2017 +0300 +++ b/njs/test/njs_unit_test.c Sun May 21 17:36:46 2017 +0000 @@ -112,6 +112,18 @@ { nxt_string("+1"), nxt_string("1") }, + { nxt_string("var a = 0x01; a"), + nxt_string("1") }, + + { nxt_string("var x = 0xffff; x"), + nxt_string("65535") }, + + { nxt_string("0x01"), + nxt_string("1") }, + + { nxt_string("0xffff"), + nxt_string("65535") }, + { nxt_string("+1\n"), nxt_string("1") }, ---------------------------------- CUT HERE -------------------------------------- Paulo Pacheco | ????? ?????? -------------- next part -------------- An HTML attachment was scrubbed... URL: From sorin.v.manole at gmail.com Sun May 21 19:23:25 2017 From: sorin.v.manole at gmail.com (Sorin Manole) Date: Sun, 21 May 2017 12:23:25 -0700 Subject: CXXFLAGS support Message-ID: Hello, Would you be willing to accept a patch to support CXX and CXXFLAGS in the nginx build logic? This could be used to write C++ nginx module code. I attached a partial implementation. Please confirm if this is the correct approach. Thanks. From sorin.v.manole at gmail.com Mon May 22 10:14:04 2017 From: sorin.v.manole at gmail.com (Sorin Manole) Date: Mon, 22 May 2017 13:14:04 +0300 Subject: CXXFLAGS support In-Reply-To: References: Message-ID: Missed attachment. 2017-05-21 22:23 GMT+03:00 Sorin Manole : > Hello, > > Would you be willing to accept a patch to support CXX and CXXFLAGS in > the nginx build logic? > This could be used to write C++ nginx module code. > I attached a partial implementation. Please confirm if this is the > correct approach. > > Thanks. -------------- next part -------------- diff -r 2c4dbcd6f2e4 auto/cc/acc --- a/auto/cc/acc Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/cc/acc Sun May 21 17:05:40 2017 +0100 @@ -8,6 +8,7 @@ # C89 mode CFLAGS="$CFLAGS -Ae" +CXXFLAGS="$CXXFLAGS -Ae" CC_TEST_FLAGS="-Ae" PCRE_OPT="$PCRE_OPT -Ae" diff -r 2c4dbcd6f2e4 auto/cc/bcc --- a/auto/cc/bcc Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/cc/bcc Sun May 21 17:05:40 2017 +0100 @@ -8,7 +8,7 @@ # optimizations # maximize speed -CFLAGS="$CFLAGS -O2" +NGX_BCC_OPT="-O2" case $CPU in pentium) @@ -27,17 +27,19 @@ # __fastcall #CPU_OPT="$CPU_OPT -pr" -CFLAGS="$CFLAGS $CPU_OPT" +NGX_BCC_OPT="$NGX_BCC_OPT $CPU_OPT" # multithreaded -CFLAGS="$CFLAGS -tWM" +NGX_BCC_OPT="$NGX_BCC_OPT -tWM" # stop on warning -CFLAGS="$CFLAGS -w!" +NGX_BCC_OPT="$NGX_BCC_OPT -w!" # disable logo -CFLAGS="$CFLAGS -q" +NGX_BCC_OPT="$NGX_BCC_OPT -q" +CFLAGS="$CFLAGS $NGX_BCC_OPT" +CXXFLAGS="$CXXFLAGS $NGX_BCC_OPT" # precompiled headers CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.csm" diff -r 2c4dbcd6f2e4 auto/cc/ccc --- a/auto/cc/ccc Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/cc/ccc Sun May 21 17:05:40 2017 +0100 @@ -9,38 +9,41 @@ # warnings -CFLAGS="$CFLAGS -msg_enable level6 -msg_fatal level6" +NGX_CCC_OPT="-msg_enable level6 -msg_fatal level6" -CFLAGS="$CFLAGS -msg_disable unknownmacro" -CFLAGS="$CFLAGS -msg_disable unusedincl" -CFLAGS="$CFLAGS -msg_disable unnecincl" -CFLAGS="$CFLAGS -msg_disable nestincl" -CFLAGS="$CFLAGS -msg_disable strctpadding" -CFLAGS="$CFLAGS -msg_disable ansialiascast" -CFLAGS="$CFLAGS -msg_disable inlinestoclsmod" -CFLAGS="$CFLAGS -msg_disable cxxkeyword" -CFLAGS="$CFLAGS -msg_disable longlongsufx" -CFLAGS="$CFLAGS -msg_disable valuepres" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable unknownmacro" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable unusedincl" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable unnecincl" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable nestincl" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable strctpadding" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable ansialiascast" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable inlinestoclsmod" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable cxxkeyword" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable longlongsufx" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable valuepres" # STUB -CFLAGS="$CFLAGS -msg_disable truncintcast" -CFLAGS="$CFLAGS -msg_disable trunclongcast" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable truncintcast" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable trunclongcast" -CFLAGS="$CFLAGS -msg_disable truncintasn" -CFLAGS="$CFLAGS -msg_disable trunclongint" -CFLAGS="$CFLAGS -msg_disable intconcastsgn" -CFLAGS="$CFLAGS -msg_disable intconstsign" -CFLAGS="$CFLAGS -msg_disable switchlong" -CFLAGS="$CFLAGS -msg_disable subscrbounds2" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable truncintasn" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable trunclongint" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable intconcastsgn" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable intconstsign" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable switchlong" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable subscrbounds2" + +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable hexoctunsign" -CFLAGS="$CFLAGS -msg_disable hexoctunsign" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable ignorecallval" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable nonstandcast" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable embedcomment" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable unreachcode" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable questcompare2" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable unusedtop" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable unrefdecl" -CFLAGS="$CFLAGS -msg_disable ignorecallval" -CFLAGS="$CFLAGS -msg_disable nonstandcast" -CFLAGS="$CFLAGS -msg_disable embedcomment" -CFLAGS="$CFLAGS -msg_disable unreachcode" -CFLAGS="$CFLAGS -msg_disable questcompare2" -CFLAGS="$CFLAGS -msg_disable unusedtop" -CFLAGS="$CFLAGS -msg_disable unrefdecl" +NGX_CCC_OPT="$NGX_CCC_OPT -msg_disable bitnotint" -CFLAGS="$CFLAGS -msg_disable bitnotint" +CFLAGS="$CFLAGS $NGX_CCC_OPT" +CXXFLAGS="$CXXFLAGS $NGX_CCC_OPT" diff -r 2c4dbcd6f2e4 auto/cc/clang --- a/auto/cc/clang Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/cc/clang Sun May 21 17:05:40 2017 +0100 @@ -58,7 +58,7 @@ CC_AUX_FLAGS="$CC_AUX_FLAGS $CPU_OPT" -CFLAGS="$CFLAGS -pipe $CPU_OPT" +NGX_CLANG_OPT="$NGX_CLANG_OPT -pipe $CPU_OPT" if [ ".$PCRE_OPT" = "." ]; then PCRE_OPT="-O2 -pipe $CPU_OPT" @@ -75,23 +75,25 @@ # warnings -CFLAGS="$CFLAGS $NGX_CLANG_OPT -Wall -Wextra -Wpointer-arith" -CFLAGS="$CFLAGS -Wconditional-uninitialized" -#CFLAGS="$CFLAGS -Wmissing-prototypes" +NGX_CLANG_OPT="$NGX_CLANG_OPT -Wall -Wextra -Wpointer-arith" +NGX_CLANG_OPT="$NGX_CLANG_OPT -Wconditional-uninitialized" +#NGX_CLANG_OPT="$NGX_CLANG_OPT -Wmissing-prototypes" # we have a lot of unused function arguments -CFLAGS="$CFLAGS -Wno-unused-parameter" +NGX_CLANG_OPT="$NGX_CLANG_OPT -Wno-unused-parameter" # deprecated system OpenSSL library on OS X if [ "$NGX_SYSTEM" = "Darwin" ]; then - CFLAGS="$CFLAGS -Wno-deprecated-declarations" + NGX_CLANG_OPT="$NGX_CLANG_OPT -Wno-deprecated-declarations" fi # stop on warning -CFLAGS="$CFLAGS -Werror" +NGX_CLANG_OPT="$NGX_CLANG_OPT -Werror" # debug -CFLAGS="$CFLAGS -g" +NGX_CLANG_OPT="$NGX_CLANG_OPT -g" + +CFLAGS="$CFLAGS $NGX_CLANG_OPT" if [ ".$CPP" = "." ]; then CPP="$CC -E" diff -r 2c4dbcd6f2e4 auto/cc/conf --- a/auto/cc/conf Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/cc/conf Sun May 21 17:05:40 2017 +0100 @@ -142,6 +142,7 @@ fi CFLAGS="$CFLAGS $NGX_CC_OPT" +CXXFLAGS="$CXXFLAGS $NGX_CXX_OPT" NGX_TEST_LD_OPT="$NGX_LD_OPT" if [ "$NGX_PLATFORM" != win32 ]; then diff -r 2c4dbcd6f2e4 auto/cc/gcc --- a/auto/cc/gcc Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/cc/gcc Sun May 21 17:05:40 2017 +0100 @@ -40,7 +40,7 @@ sun4u | sun4v | sparc | sparc64 ) # "-mcpu=v9" enables the "casa" assembler instruction - CFLAGS="$CFLAGS -mcpu=v9" + NGX_GCC_OPT="-mcpu=v9" ;; esac @@ -48,11 +48,11 @@ # optimizations -#NGX_GCC_OPT="-O2" -#NGX_GCC_OPT="-Os" -NGX_GCC_OPT="-O" +#NGX_GCC_OPTIM="$NGX_GCC_OPTIM -O2" +#NGX_GCC_OPTIM="$NGX_GCC_OPTIM -Os" +NGX_GCC_OPTIM="$NGX_GCC_OPTIM -O" -#CFLAGS="$CFLAGS -fomit-frame-pointer" +#NGX_GCC_OPT="$NGX_GCC_OPT -fomit-frame-pointer" case $CPU in pentium) @@ -120,7 +120,7 @@ esac -CFLAGS="$CFLAGS $PIPE $CPU_OPT" +NGX_GCC_OPT="$NGX_GCC_OPT $PIPE $CPU_OPT" if [ ".$PCRE_OPT" = "." ]; then PCRE_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT" @@ -138,41 +138,41 @@ # warnings # -W requires at least -O -CFLAGS="$CFLAGS ${NGX_GCC_OPT:--O} -W" +NGX_GCC_OPT="$NGX_GCC_OPT ${NGX_GCC_OPTIM:--O} -W" -CFLAGS="$CFLAGS -Wall -Wpointer-arith" -#CFLAGS="$CFLAGS -Wconversion" -#CFLAGS="$CFLAGS -Winline" -#CFLAGS="$CFLAGS -Wmissing-prototypes" +NGX_GCC_OPT="$NGX_GCC_OPT -Wall -Wpointer-arith" +#NGX_GCC_OPT="$NGX_GCC_OPT -Wconversion" +#NGX_GCC_OPT="$NGX_GCC_OPT -Winline" +#NGX_GCC_OPT="$NGX_GCC_OPT -Wmissing-prototypes" case "$NGX_GCC_VER" in 2.*) # we have a lot of the unused function arguments - CFLAGS="$CFLAGS -Wno-unused" + NGX_GCC_OPT="$NGX_GCC_OPT -Wno-unused" ;; *) # we have a lot of the unused function arguments - CFLAGS="$CFLAGS -Wno-unused-parameter" + NGX_GCC_OPT="$NGX_GCC_OPT -Wno-unused-parameter" # 4.2.1 shows the warning in wrong places - #CFLAGS="$CFLAGS -Wunreachable-code" + #NGX_GCC_OPT="$NGX_GCC_OPT -Wunreachable-code" # deprecated system OpenSSL library on OS X if [ "$NGX_SYSTEM" = "Darwin" ]; then - CFLAGS="$CFLAGS -Wno-deprecated-declarations" + NGX_GCC_OPT="$NGX_GCC_OPT -Wno-deprecated-declarations" fi ;; esac # stop on warning -CFLAGS="$CFLAGS -Werror" +NGX_GCC_OPT="$NGX_GCC_OPT -Werror" # debug -CFLAGS="$CFLAGS -g" +NGX_GCC_OPT="$NGX_GCC_OPT -g" # DragonFly's gcc3 generates DWARF -#CFLAGS="$CFLAGS -g -gstabs" +#NGX_GCC_OPT="$NGX_GCC_OPT -g -gstabs" if [ ".$CPP" = "." ]; then CPP="$CC -E" diff -r 2c4dbcd6f2e4 auto/cc/icc --- a/auto/cc/icc Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/cc/icc Sun May 21 17:05:40 2017 +0100 @@ -15,7 +15,7 @@ # optimizations -CFLAGS="$CFLAGS -O" +NGX_ICC_OPT="-O" CORE_LINK="$CORE_LINK -opt_report_file=$NGX_OBJS/opt_report_file" @@ -37,7 +37,7 @@ ;; esac -CFLAGS="$CFLAGS $CPU_OPT" +NGX_ICC_OPT="$NGX_ICC_OPT $CPU_OPT" if [ ".$PCRE_OPT" = "." ]; then PCRE_OPT="-O $CPU_OPT" @@ -50,60 +50,60 @@ # warnings -CFLAGS="$CFLAGS -w2" +NGX_ICC_OPT="$NGX_ICC_OPT -w2" # disable some warnings # invalid type conversion: "int" to "char *" -CFLAGS="$CFLAGS -wd171" +NGX_ICC_OPT="$NGX_ICC_OPT -wd171" # argument is incompatible with corresponding format string conversion -CFLAGS="$CFLAGS -wd181" +NGX_ICC_OPT="$NGX_ICC_OPT -wd181" # zero used for undefined preprocessing identifier -CFLAGS="$CFLAGS -wd193" +NGX_ICC_OPT="$NGX_ICC_OPT -wd193" # the format string ends before this argument -CFLAGS="$CFLAGS -wd268" +NGX_ICC_OPT="$NGX_ICC_OPT -wd268" # invalid format string conversion -CFLAGS="$CFLAGS -wd269" +NGX_ICC_OPT="$NGX_ICC_OPT -wd269" # conversion from "long long" to "size_t" may lose significant bits -CFLAGS="$CFLAGS -wd810" +NGX_ICC_OPT="$NGX_ICC_OPT -wd810" # parameter was never referenced -CFLAGS="$CFLAGS -wd869" +NGX_ICC_OPT="$NGX_ICC_OPT -wd869" # attribute "unused" is only allowed in a function definition, warning on pTHX_ -CFLAGS="$CFLAGS -wd1301" +NGX_ICC_OPT="$NGX_ICC_OPT -wd1301" # STUB # enumerated type mixed with another type -CFLAGS="$CFLAGS -wd188" +NGX_ICC_OPT="$NGX_ICC_OPT -wd188" # controlling expression is constant -CFLAGS="$CFLAGS -wd279" +NGX_ICC_OPT="$NGX_ICC_OPT -wd279" # operands are evaluated in unspecified order -CFLAGS="$CFLAGS -wd981" +NGX_ICC_OPT="$NGX_ICC_OPT -wd981" # external definition with no prior declaration -CFLAGS="$CFLAGS -wd1418" +NGX_ICC_OPT="$NGX_ICC_OPT -wd1418" # external declaration in primary source file -CFLAGS="$CFLAGS -wd1419" +NGX_ICC_OPT="$NGX_ICC_OPT -wd1419" case "$NGX_ICC_VER" in 9.*) # "cc" clobber ignored, warnings for Linux's htonl()/htons() - CFLAGS="$CFLAGS -wd1469" + NGX_ICC_OPT="$NGX_ICC_OPT -wd1469" # explicit conversion of a 64-bit integral type to a smaller # integral type - CFLAGS="$CFLAGS -wd1683" + NGX_ICC_OPT="$NGX_ICC_OPT -wd1683" # conversion from pointer to same-sized integral type, # warning on offsetof() - CFLAGS="$CFLAGS -wd1684" + NGX_ICC_OPT="$NGX_ICC_OPT -wd1684" # floating-point equality and inequality comparisons are unreliable, # warning on SvTRUE() - CFLAGS="$CFLAGS -wd1572" + NGX_ICC_OPT="$NGX_ICC_OPT -wd1572" ;; 8.*) # "cc" clobber ignored, warnings for Linux's htonl()/htons() - CFLAGS="$CFLAGS -wd1469" + NGX_ICC_OPT="$NGX_ICC_OPT -wd1469" # floating-point equality and inequality comparisons are unreliable, # warning on SvTRUE() - CFLAGS="$CFLAGS -wd1572" + NGX_ICC_OPT="$NGX_ICC_OPT -wd1572" ;; *) @@ -111,7 +111,10 @@ esac # stop on warning -CFLAGS="$CFLAGS -Werror" +NGX_ICC_OPT="$NGX_ICC_OPT -Werror" # debug -CFLAGS="$CFLAGS -g" +NGX_ICC_OPT="$NGX_ICC_OPT -g" + +CFLAGS="$CFLAGS $NGX_ICC_OPT" +CXXFLAGS="$CXXFLAGS $NGX_ICC_OPT" diff -r 2c4dbcd6f2e4 auto/make --- a/auto/make Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/make Sun May 21 17:05:40 2017 +0100 @@ -21,9 +21,11 @@ cat << END > $NGX_MAKEFILE CC = $CC +CXX = $CXX CFLAGS = $CFLAGS -CPP = $CPP -LINK = $LINK +CXXFLAGS = $CXXFLAGS +CPP = $CPP +LINK = $LINK END @@ -384,8 +386,9 @@ ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" - for ngx_src in $MISC_SRCS + for ngx_src in $NGX_MISC_SRCS do + ngx_src_is_cpp=`echo $ngx_src | grep -E "\.cpp$" | wc -l` ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` ngx_obj=`echo $ngx_src \ | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \ @@ -393,6 +396,12 @@ -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \ -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"` + if [ "$ngx_src_is_cpp" -eq '1' ]; then + ngx_cc="\$(CXX) $ngx_compile_opt \$(CXXFLAGS) $ngx_use_pch \$(ALL_INCS)" + else + ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" + fi; + cat << END >> $NGX_MAKEFILE $ngx_obj: \$(CORE_DEPS) $ngx_cont$ngx_src @@ -408,10 +417,10 @@ if test -n "$NGX_ADDON_SRCS"; then - ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" - for ngx_src in $NGX_ADDON_SRCS do + ngx_src_is_cpp=`echo $ngx_src | grep -E "\.cpp$" | wc -l` + ngx_obj="addon/`basename \`dirname $ngx_src\``" ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \ @@ -424,6 +433,12 @@ -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"` ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` + if [ "$ngx_src_is_cpp" -eq '1' ]; then + ngx_cc="\$(CXX) $ngx_compile_opt \$(CXXFLAGS) $ngx_use_pch \$(ALL_INCS)" + else + ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" + fi; + cat << END >> $NGX_MAKEFILE diff -r 2c4dbcd6f2e4 auto/options --- a/auto/options Mon Apr 24 14:17:13 2017 +0300 +++ b/auto/options Sun May 21 17:05:40 2017 +0100 @@ -23,6 +23,7 @@ NGX_DEBUG=NO NGX_CC_OPT= +NGX_CXX_OPT= NGX_LD_OPT= CPU=NO @@ -333,8 +334,10 @@ --with-compat) NGX_COMPAT=YES ;; --with-cc=*) CC="$value" ;; + --with-cxx=*) CXX="$value" ;; --with-cpp=*) CPP="$value" ;; --with-cc-opt=*) NGX_CC_OPT="$value" ;; + --with-cxx-opt=*) NGX_CXX_OPT="$value" ;; --with-ld-opt=*) NGX_LD_OPT="$value" ;; --with-cpu-opt=*) CPU="$value" ;; --with-debug) NGX_DEBUG=YES ;; @@ -541,8 +544,10 @@ --with-compat dynamic modules compatibility --with-cc=PATH set C compiler pathname + --with-cxx=PATH set C++ compiler pathname --with-cpp=PATH set C preprocessor pathname --with-cc-opt=OPTIONS set additional C compiler options + --with-cxx-opt=OPTIONS set additional C++ compiler options --with-ld-opt=OPTIONS set additional linker options --with-cpu-opt=CPU build for the specified CPU, valid values: pentium, pentiumpro, pentium3, pentium4, From mdounin at mdounin.ru Mon May 22 13:18:46 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 22 May 2017 16:18:46 +0300 Subject: Http: make ngx_http_init_listening a public api In-Reply-To: References: <210D48C7-4B05-479F-BFF8-935D1326362E@lvht.net> <20170518175038.GU55433@mdounin.ru> <8718AAE9-65EB-4F66-805C-9F8DCC7C4113> <20170519175554.GA55433@mdounin.ru> Message-ID: <20170522131846.GE55433@mdounin.ru> Hello! On Mon, May 22, 2017 at 01:17:40AM +0800, ?? (hucc) wrote: > Hi, > > On Saturday, May 20, 2017 1:55 AM +0300, Maxim Dounin wrote: > > >On Fri, May 19, 2017 at 03:04:43AM +0800, 0 at lvht.net wrote: > > > >> Thank you for your reply. > >> ******** > >> Please let me assume it make sense to make nginx work as a > >> standalone websock server. The problem we will face is that we > >> cannot send message to client. Because when the client initial > >> tcp connection, the connection will be processed by one worker > >> uncertainly. If we want push message to one client, we must find > >> the worker processing this client connection. > >> ********* > >> It is also impossible to add new listening port to an http > >> server directive dynamically in the websocket model, but it will > >> be a huge burden to sync this logic to the http model. So I > >> propose nginx to open this api. > > > >Thank you for the detailed explanation. > > > >So, you are trying to introduce per-process listening sockets in > >order to be able to communicate with a particular worker process. > > > >This is highly unlikely to work properly without deep integration > >with nginx itself, and/or will be broken by trivial unrelated > >changes in nginx. So the answer is still negative. > > > >If you want to try to address the problem properly, consider the > >following approaches: > > > >- create listening sockets yourself, and handle connections in > > your module; > > > >- introduce per-process listining sockets in nginx core; likely > > there will many obscure problems though, including things like > > what to do on graceful shutdown; > > > >- use interprocess communication instead - for example, nginx has > > shared memory available to modules (there are also channels to > > pass messages between processes, but these are not currently > > available to modules). > > It is necessary to introduce per-process listening sockets in nginx core. > Laster year, I have done most of the work, when I found it is hard to establish > the connection to push data to another process in ngx_rtmp_auto_push_moudle. > The problem can be solved by introduce a flag aloneport in ngx_listening_t and > work with ls->worker. The configuration is listen ** [aloneport=ngx_worder]. > And as far as I know, there is an obscure problem which is what to do on reload > when new worker_processes number is less than the no-update ngx_worker of > aloneport. As for the problem about what to do on graceful shutdown, I still > don`t get it. Besides, I hope that arut will provide some ideas. > Another problem/idea found in ngx_rtmp_module, it is also necessary to introduce > a config options like NGX_3RD_CORE_MODULES (or other way or options) to ensure > the 3rd party CORE modules is behind ngx_events_module. It is going to solve > some obscure problems where the solution in ngx_rtmp_module is unfriendly > and incomprehensible. > > If you guys also think it is needed, I will provide the patch of aloneport > once time permits. I personally think that per-process listening sockets is not a good solution from architectural point of view - while they provide something immediate and easy-to-use, they 1) introduce (likely unsolvable) problems during shutdown / configuration reload, and 2) they don't really solve anything as long as the problem is a little bit more complicated than "send something to one client" - for example, it is not possible to send something to a group of clients. Not to mention that it is very non-trivial to use if you don't know ports in advance, and also breaks basic nginx model of multiple identical worker processes. So, just for the record: I don't think it is needed, and would rather suggest to improve interprocess communications instead. I can be convinced that it is needed though, as long as benefits are clearly demonstrated and downsides are understood and addressed somehow. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Mon May 22 13:44:40 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 22 May 2017 13:44:40 +0000 Subject: [nginx] Contrib: proper syntax parsing in vim syntax highlighting. Message-ID: details: http://hg.nginx.org/nginx/rev/7943298d4ac0 branches: changeset: 7003:7943298d4ac0 user: Maxim Dounin date: Mon May 22 16:34:47 2017 +0300 description: Contrib: proper syntax parsing in vim syntax highlighting. Instead of highlighting directives in arbitrary positions, proper parsing of nginx.conf syntax was implemented, matching what nginx does internally. This allows vim to correctly highlight various complex cases, including: return 301 http://example.com/path#fragment"; and also avoids highlighting of parameters as directives, as in server_name missing.semicolon.example.com index index.php; where "index" is not a directive but a parameter of the "server_name" directive due to missing semicolon. Most important downside of this approach seems to be that there is no easy way to introduce directive-specific parameters. As such, only "listen" directive parameters were preserved. diffstat: contrib/vim/syntax/nginx.vim | 3452 +++++++++++++++++++++-------------------- 1 files changed, 1741 insertions(+), 1711 deletions(-) diffs (truncated from 3884 to 1000 lines): diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim --- a/contrib/vim/syntax/nginx.vim +++ b/contrib/vim/syntax/nginx.vim @@ -5,2115 +5,2145 @@ if exists("b:current_syntax") finish end -setlocal iskeyword+=. -setlocal iskeyword+=/ -setlocal iskeyword+=: - -syn match ngxVariable '\$\(\w\+\|{\w\+}\)' -syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained -syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained -syn region ngxBlock start=+^+ end=+{+ skip=+\${+ contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline -syn region ngxString start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString -syn match ngxComment ' *#.*$' - -syn keyword ngxBoolean on -syn keyword ngxBoolean off - -syn keyword ngxDirectiveBlock http contained -syn keyword ngxDirectiveBlock mail contained -syn keyword ngxDirectiveBlock events contained -syn keyword ngxDirectiveBlock server contained -syn keyword ngxDirectiveBlock types contained -syn keyword ngxDirectiveBlock location contained -syn keyword ngxDirectiveBlock upstream contained -syn keyword ngxDirectiveBlock charset_map contained -syn keyword ngxDirectiveBlock limit_except contained -syn keyword ngxDirectiveBlock if contained -syn keyword ngxDirectiveBlock geo contained -syn keyword ngxDirectiveBlock map contained -syn keyword ngxDirectiveBlock split_clients contained - -syn keyword ngxDirectiveImportant include -syn keyword ngxDirectiveImportant root -syn keyword ngxDirectiveImportant server -syn keyword ngxDirectiveImportant server_name -syn keyword ngxDirectiveImportant listen contained -syn region ngxDirectiveImportantListen matchgroup=ngxDirectiveImportant start=+listen+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxListenOptions,ngxString -syn keyword ngxDirectiveImportant internal -syn keyword ngxDirectiveImportant proxy_pass -syn keyword ngxDirectiveImportant memcached_pass -syn keyword ngxDirectiveImportant fastcgi_pass -syn keyword ngxDirectiveImportant scgi_pass -syn keyword ngxDirectiveImportant uwsgi_pass -syn keyword ngxDirectiveImportant try_files - -syn keyword ngxListenOptions default_server contained -syn keyword ngxListenOptions ssl contained -syn keyword ngxListenOptions http2 contained -syn keyword ngxListenOptions spdy contained -syn keyword ngxListenOptions proxy_protocol contained -syn keyword ngxListenOptions setfib contained -syn keyword ngxListenOptions fastopen contained -syn keyword ngxListenOptions backlog contained -syn keyword ngxListenOptions rcvbuf contained -syn keyword ngxListenOptions sndbuf contained -syn keyword ngxListenOptions accept_filter contained -syn keyword ngxListenOptions deferred contained -syn keyword ngxListenOptions bind contained -syn keyword ngxListenOptions ipv6only contained -syn keyword ngxListenOptions reuseport contained -syn keyword ngxListenOptions so_keepalive contained -syn keyword ngxListenOptions keepidle contained - -syn keyword ngxDirectiveControl break -syn keyword ngxDirectiveControl return -syn keyword ngxDirectiveControl rewrite -syn keyword ngxDirectiveControl set - -syn keyword ngxDirectiveError error_page -syn keyword ngxDirectiveError post_action - -syn keyword ngxDirectiveDeprecated connections -syn keyword ngxDirectiveDeprecated imap -syn keyword ngxDirectiveDeprecated limit_zone -syn keyword ngxDirectiveDeprecated mysql_test -syn keyword ngxDirectiveDeprecated open_file_cache_retest -syn keyword ngxDirectiveDeprecated optimize_server_names -syn keyword ngxDirectiveDeprecated satisfy_any -syn keyword ngxDirectiveDeprecated so_keepalive +" general syntax -syn keyword ngxDirective absolute_redirect -syn keyword ngxDirective accept_mutex -syn keyword ngxDirective accept_mutex_delay -syn keyword ngxDirective acceptex_read -syn keyword ngxDirective access_log -syn keyword ngxDirective add_after_body -syn keyword ngxDirective add_before_body -syn keyword ngxDirective add_header -syn keyword ngxDirective addition_types -syn keyword ngxDirective aio -syn keyword ngxDirective aio_write -syn keyword ngxDirective alias -syn keyword ngxDirective allow -syn keyword ngxDirective ancient_browser -syn keyword ngxDirective ancient_browser_value -syn keyword ngxDirective auth_basic -syn keyword ngxDirective auth_basic_user_file -syn keyword ngxDirective auth_http -syn keyword ngxDirective auth_http_header -syn keyword ngxDirective auth_http_pass_client_cert -syn keyword ngxDirective auth_http_timeout -syn keyword ngxDirective auth_jwt -syn keyword ngxDirective auth_jwt_key_file -syn keyword ngxDirective auth_request -syn keyword ngxDirective auth_request_set -syn keyword ngxDirective autoindex -syn keyword ngxDirective autoindex_exact_size -syn keyword ngxDirective autoindex_format -syn keyword ngxDirective autoindex_localtime -syn keyword ngxDirective charset -syn keyword ngxDirective charset_map -syn keyword ngxDirective charset_types -syn keyword ngxDirective chunked_transfer_encoding -syn keyword ngxDirective client_body_buffer_size -syn keyword ngxDirective client_body_in_file_only -syn keyword ngxDirective client_body_in_single_buffer -syn keyword ngxDirective client_body_temp_path -syn keyword ngxDirective client_body_timeout -syn keyword ngxDirective client_header_buffer_size -syn keyword ngxDirective client_header_timeout -syn keyword ngxDirective client_max_body_size -syn keyword ngxDirective connection_pool_size -syn keyword ngxDirective create_full_put_path -syn keyword ngxDirective daemon -syn keyword ngxDirective dav_access -syn keyword ngxDirective dav_methods -syn keyword ngxDirective debug_connection -syn keyword ngxDirective debug_points -syn keyword ngxDirective default_type -syn keyword ngxDirective degradation -syn keyword ngxDirective degrade -syn keyword ngxDirective deny -syn keyword ngxDirective devpoll_changes -syn keyword ngxDirective devpoll_events -syn keyword ngxDirective directio -syn keyword ngxDirective directio_alignment -syn keyword ngxDirective disable_symlinks -syn keyword ngxDirective empty_gif -syn keyword ngxDirective env -syn keyword ngxDirective epoll_events -syn keyword ngxDirective error_log -syn keyword ngxDirective etag -syn keyword ngxDirective eventport_events -syn keyword ngxDirective expires -syn keyword ngxDirective f4f -syn keyword ngxDirective f4f_buffer_size -syn keyword ngxDirective fastcgi_bind -syn keyword ngxDirective fastcgi_buffer_size -syn keyword ngxDirective fastcgi_buffering -syn keyword ngxDirective fastcgi_buffers -syn keyword ngxDirective fastcgi_busy_buffers_size -syn keyword ngxDirective fastcgi_cache -syn keyword ngxDirective fastcgi_cache_bypass -syn keyword ngxDirective fastcgi_cache_key -syn keyword ngxDirective fastcgi_cache_lock -syn keyword ngxDirective fastcgi_cache_lock_age -syn keyword ngxDirective fastcgi_cache_lock_timeout -syn keyword ngxDirective fastcgi_cache_max_range_offset -syn keyword ngxDirective fastcgi_cache_methods -syn keyword ngxDirective fastcgi_cache_min_uses -syn keyword ngxDirective fastcgi_cache_path -syn keyword ngxDirective fastcgi_cache_purge -syn keyword ngxDirective fastcgi_cache_revalidate -syn keyword ngxDirective fastcgi_cache_use_stale -syn keyword ngxDirective fastcgi_cache_valid -syn keyword ngxDirective fastcgi_catch_stderr -syn keyword ngxDirective fastcgi_connect_timeout -syn keyword ngxDirective fastcgi_force_ranges -syn keyword ngxDirective fastcgi_hide_header -syn keyword ngxDirective fastcgi_ignore_client_abort -syn keyword ngxDirective fastcgi_ignore_headers -syn keyword ngxDirective fastcgi_index -syn keyword ngxDirective fastcgi_intercept_errors -syn keyword ngxDirective fastcgi_keep_conn -syn keyword ngxDirective fastcgi_limit_rate -syn keyword ngxDirective fastcgi_max_temp_file_size -syn keyword ngxDirective fastcgi_next_upstream -syn keyword ngxDirective fastcgi_next_upstream_timeout -syn keyword ngxDirective fastcgi_next_upstream_tries -syn keyword ngxDirective fastcgi_no_cache -syn keyword ngxDirective fastcgi_param -syn keyword ngxDirective fastcgi_pass_header -syn keyword ngxDirective fastcgi_pass_request_body -syn keyword ngxDirective fastcgi_pass_request_headers -syn keyword ngxDirective fastcgi_read_timeout -syn keyword ngxDirective fastcgi_request_buffering -syn keyword ngxDirective fastcgi_send_lowat -syn keyword ngxDirective fastcgi_send_timeout -syn keyword ngxDirective fastcgi_split_path_info -syn keyword ngxDirective fastcgi_store -syn keyword ngxDirective fastcgi_store_access -syn keyword ngxDirective fastcgi_temp_file_write_size -syn keyword ngxDirective fastcgi_temp_path -syn keyword ngxDirective flv -syn keyword ngxDirective geoip_city -syn keyword ngxDirective geoip_country -syn keyword ngxDirective geoip_org -syn keyword ngxDirective geoip_proxy -syn keyword ngxDirective geoip_proxy_recursive -syn keyword ngxDirective google_perftools_profiles -syn keyword ngxDirective gunzip -syn keyword ngxDirective gunzip_buffers -syn keyword ngxDirective gzip -syn keyword ngxDirective gzip_buffers -syn keyword ngxDirective gzip_comp_level -syn keyword ngxDirective gzip_disable -syn keyword ngxDirective gzip_hash -syn keyword ngxDirective gzip_http_version -syn keyword ngxDirective gzip_min_length -syn keyword ngxDirective gzip_no_buffer -syn keyword ngxDirective gzip_proxied -syn keyword ngxDirective gzip_static -syn keyword ngxDirective gzip_types -syn keyword ngxDirective gzip_vary -syn keyword ngxDirective gzip_window -syn keyword ngxDirective hash -syn keyword ngxDirective health_check -syn keyword ngxDirective health_check_timeout -syn keyword ngxDirective hls -syn keyword ngxDirective hls_buffers -syn keyword ngxDirective hls_forward_args -syn keyword ngxDirective hls_fragment -syn keyword ngxDirective hls_mp4_buffer_size -syn keyword ngxDirective hls_mp4_max_buffer_size -syn keyword ngxDirective http2_chunk_size -syn keyword ngxDirective http2_body_preread_size -syn keyword ngxDirective http2_idle_timeout -syn keyword ngxDirective http2_max_concurrent_streams -syn keyword ngxDirective http2_max_field_size -syn keyword ngxDirective http2_max_header_size -syn keyword ngxDirective http2_max_requests -syn keyword ngxDirective http2_recv_buffer_size -syn keyword ngxDirective http2_recv_timeout -syn keyword ngxDirective if_modified_since -syn keyword ngxDirective ignore_invalid_headers -syn keyword ngxDirective image_filter -syn keyword ngxDirective image_filter_buffer -syn keyword ngxDirective image_filter_interlace -syn keyword ngxDirective image_filter_jpeg_quality -syn keyword ngxDirective image_filter_sharpen -syn keyword ngxDirective image_filter_transparency -syn keyword ngxDirective image_filter_webp_quality -syn keyword ngxDirective imap_auth -syn keyword ngxDirective imap_capabilities -syn keyword ngxDirective imap_client_buffer -syn keyword ngxDirective index -syn keyword ngxDirective iocp_threads -syn keyword ngxDirective ip_hash -syn keyword ngxDirective js_access -syn keyword ngxDirective js_content -syn keyword ngxDirective js_filter -syn keyword ngxDirective js_include -syn keyword ngxDirective js_preread -syn keyword ngxDirective js_set -syn keyword ngxDirective keepalive -syn keyword ngxDirective keepalive_disable -syn keyword ngxDirective keepalive_requests -syn keyword ngxDirective keepalive_timeout -syn keyword ngxDirective kqueue_changes -syn keyword ngxDirective kqueue_events -syn keyword ngxDirective large_client_header_buffers -syn keyword ngxDirective least_conn -syn keyword ngxDirective least_time -syn keyword ngxDirective limit_conn -syn keyword ngxDirective limit_conn_log_level -syn keyword ngxDirective limit_conn_status -syn keyword ngxDirective limit_conn_zone -syn keyword ngxDirective limit_rate -syn keyword ngxDirective limit_rate_after -syn keyword ngxDirective limit_req -syn keyword ngxDirective limit_req_log_level -syn keyword ngxDirective limit_req_status -syn keyword ngxDirective limit_req_zone -syn keyword ngxDirective lingering_close -syn keyword ngxDirective lingering_time -syn keyword ngxDirective lingering_timeout -syn keyword ngxDirective load_module -syn keyword ngxDirective lock_file -syn keyword ngxDirective log_format -syn keyword ngxDirective log_not_found -syn keyword ngxDirective log_subrequest -syn keyword ngxDirective map_hash_bucket_size -syn keyword ngxDirective map_hash_max_size -syn keyword ngxDirective match -syn keyword ngxDirective master_process -syn keyword ngxDirective max_ranges -syn keyword ngxDirective memcached_bind -syn keyword ngxDirective memcached_buffer_size -syn keyword ngxDirective memcached_connect_timeout -syn keyword ngxDirective memcached_force_ranges -syn keyword ngxDirective memcached_gzip_flag -syn keyword ngxDirective memcached_next_upstream -syn keyword ngxDirective memcached_next_upstream_timeout -syn keyword ngxDirective memcached_next_upstream_tries -syn keyword ngxDirective memcached_read_timeout -syn keyword ngxDirective memcached_send_timeout -syn keyword ngxDirective merge_slashes -syn keyword ngxDirective min_delete_depth -syn keyword ngxDirective modern_browser -syn keyword ngxDirective modern_browser_value -syn keyword ngxDirective mp4 -syn keyword ngxDirective mp4_buffer_size -syn keyword ngxDirective mp4_max_buffer_size -syn keyword ngxDirective mp4_limit_rate -syn keyword ngxDirective mp4_limit_rate_after -syn keyword ngxDirective msie_padding -syn keyword ngxDirective msie_refresh -syn keyword ngxDirective multi_accept -syn keyword ngxDirective ntlm -syn keyword ngxDirective open_file_cache -syn keyword ngxDirective open_file_cache_errors -syn keyword ngxDirective open_file_cache_events -syn keyword ngxDirective open_file_cache_min_uses -syn keyword ngxDirective open_file_cache_valid -syn keyword ngxDirective open_log_file_cache -syn keyword ngxDirective output_buffers -syn keyword ngxDirective override_charset -syn keyword ngxDirective pcre_jit -syn keyword ngxDirective perl -syn keyword ngxDirective perl_modules -syn keyword ngxDirective perl_require -syn keyword ngxDirective perl_set -syn keyword ngxDirective pid -syn keyword ngxDirective pop3_auth -syn keyword ngxDirective pop3_capabilities -syn keyword ngxDirective port_in_redirect -syn keyword ngxDirective post_acceptex -syn keyword ngxDirective postpone_gzipping -syn keyword ngxDirective postpone_output -syn keyword ngxDirective preread_buffer_size -syn keyword ngxDirective preread_timeout -syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite -syn keyword ngxMailProtocol imap pop3 smtp contained -syn keyword ngxDirective proxy -syn keyword ngxDirective proxy_bind -syn keyword ngxDirective proxy_buffer -syn keyword ngxDirective proxy_buffer_size -syn keyword ngxDirective proxy_buffering -syn keyword ngxDirective proxy_buffers -syn keyword ngxDirective proxy_busy_buffers_size -syn keyword ngxDirective proxy_cache -syn keyword ngxDirective proxy_cache_bypass -syn keyword ngxDirective proxy_cache_convert_head -syn keyword ngxDirective proxy_cache_key -syn keyword ngxDirective proxy_cache_lock -syn keyword ngxDirective proxy_cache_lock_age -syn keyword ngxDirective proxy_cache_lock_timeout -syn keyword ngxDirective proxy_cache_max_range_offset -syn keyword ngxDirective proxy_cache_methods -syn keyword ngxDirective proxy_cache_min_uses -syn keyword ngxDirective proxy_cache_path -syn keyword ngxDirective proxy_cache_purge -syn keyword ngxDirective proxy_cache_revalidate -syn keyword ngxDirective proxy_cache_use_stale -syn keyword ngxDirective proxy_cache_valid -syn keyword ngxDirective proxy_connect_timeout -syn keyword ngxDirective proxy_cookie_domain -syn keyword ngxDirective proxy_cookie_path -syn keyword ngxDirective proxy_download_rate -syn keyword ngxDirective proxy_force_ranges -syn keyword ngxDirective proxy_headers_hash_bucket_size -syn keyword ngxDirective proxy_headers_hash_max_size -syn keyword ngxDirective proxy_hide_header -syn keyword ngxDirective proxy_http_version -syn keyword ngxDirective proxy_ignore_client_abort -syn keyword ngxDirective proxy_ignore_headers -syn keyword ngxDirective proxy_intercept_errors -syn keyword ngxDirective proxy_limit_rate -syn keyword ngxDirective proxy_max_temp_file_size -syn keyword ngxDirective proxy_method -syn keyword ngxDirective proxy_next_upstream -syn keyword ngxDirective proxy_next_upstream_timeout -syn keyword ngxDirective proxy_next_upstream_tries -syn keyword ngxDirective proxy_no_cache -syn keyword ngxDirective proxy_pass_error_message -syn keyword ngxDirective proxy_pass_header -syn keyword ngxDirective proxy_pass_request_body -syn keyword ngxDirective proxy_pass_request_headers -syn keyword ngxDirective proxy_protocol -syn keyword ngxDirective proxy_protocol_timeout -syn keyword ngxDirective proxy_read_timeout -syn keyword ngxDirective proxy_redirect -syn keyword ngxDirective proxy_request_buffering -syn keyword ngxDirective proxy_responses -syn keyword ngxDirective proxy_send_lowat -syn keyword ngxDirective proxy_send_timeout -syn keyword ngxDirective proxy_set_body -syn keyword ngxDirective proxy_set_header -syn keyword ngxDirective proxy_ssl_certificate -syn keyword ngxDirective proxy_ssl_certificate_key -syn keyword ngxDirective proxy_ssl_ciphers -syn keyword ngxDirective proxy_ssl_crl -syn keyword ngxDirective proxy_ssl_name -syn keyword ngxDirective proxy_ssl_password_file -syn keyword ngxDirective proxy_ssl_protocols nextgroup=ngxSSLProtocol skipwhite -syn keyword ngxDirective proxy_ssl_server_name -syn keyword ngxDirective proxy_ssl_session_reuse -syn keyword ngxDirective proxy_ssl_trusted_certificate -syn keyword ngxDirective proxy_ssl_verify -syn keyword ngxDirective proxy_ssl_verify_depth -syn keyword ngxDirective proxy_store -syn keyword ngxDirective proxy_store_access -syn keyword ngxDirective proxy_temp_file_write_size -syn keyword ngxDirective proxy_temp_path -syn keyword ngxDirective proxy_timeout -syn keyword ngxDirective proxy_upload_rate -syn keyword ngxDirective queue -syn keyword ngxDirective random_index -syn keyword ngxDirective read_ahead -syn keyword ngxDirective real_ip_header -syn keyword ngxDirective real_ip_recursive -syn keyword ngxDirective recursive_error_pages -syn keyword ngxDirective referer_hash_bucket_size -syn keyword ngxDirective referer_hash_max_size -syn keyword ngxDirective request_pool_size -syn keyword ngxDirective reset_timedout_connection -syn keyword ngxDirective resolver -syn keyword ngxDirective resolver_timeout -syn keyword ngxDirective rewrite_log -syn keyword ngxDirective rtsig_overflow_events -syn keyword ngxDirective rtsig_overflow_test -syn keyword ngxDirective rtsig_overflow_threshold -syn keyword ngxDirective rtsig_signo -syn keyword ngxDirective satisfy -syn keyword ngxDirective scgi_bind -syn keyword ngxDirective scgi_buffer_size -syn keyword ngxDirective scgi_buffering -syn keyword ngxDirective scgi_buffers -syn keyword ngxDirective scgi_busy_buffers_size -syn keyword ngxDirective scgi_cache -syn keyword ngxDirective scgi_cache_bypass -syn keyword ngxDirective scgi_cache_key -syn keyword ngxDirective scgi_cache_lock -syn keyword ngxDirective scgi_cache_lock_age -syn keyword ngxDirective scgi_cache_lock_timeout -syn keyword ngxDirective scgi_cache_max_range_offset -syn keyword ngxDirective scgi_cache_methods -syn keyword ngxDirective scgi_cache_min_uses -syn keyword ngxDirective scgi_cache_path -syn keyword ngxDirective scgi_cache_purge -syn keyword ngxDirective scgi_cache_revalidate -syn keyword ngxDirective scgi_cache_use_stale -syn keyword ngxDirective scgi_cache_valid -syn keyword ngxDirective scgi_connect_timeout -syn keyword ngxDirective scgi_force_ranges -syn keyword ngxDirective scgi_hide_header -syn keyword ngxDirective scgi_ignore_client_abort -syn keyword ngxDirective scgi_ignore_headers -syn keyword ngxDirective scgi_intercept_errors -syn keyword ngxDirective scgi_limit_rate -syn keyword ngxDirective scgi_max_temp_file_size -syn keyword ngxDirective scgi_next_upstream -syn keyword ngxDirective scgi_next_upstream_timeout -syn keyword ngxDirective scgi_next_upstream_tries -syn keyword ngxDirective scgi_no_cache -syn keyword ngxDirective scgi_param -syn keyword ngxDirective scgi_pass_header -syn keyword ngxDirective scgi_pass_request_body -syn keyword ngxDirective scgi_pass_request_headers -syn keyword ngxDirective scgi_read_timeout -syn keyword ngxDirective scgi_request_buffering -syn keyword ngxDirective scgi_send_timeout -syn keyword ngxDirective scgi_store -syn keyword ngxDirective scgi_store_access -syn keyword ngxDirective scgi_temp_file_write_size -syn keyword ngxDirective scgi_temp_path -syn keyword ngxDirective secure_link -syn keyword ngxDirective secure_link_md5 -syn keyword ngxDirective secure_link_secret -syn keyword ngxDirective send_lowat -syn keyword ngxDirective send_timeout -syn keyword ngxDirective sendfile -syn keyword ngxDirective sendfile_max_chunk -syn keyword ngxDirective server_name_in_redirect -syn keyword ngxDirective server_names_hash_bucket_size -syn keyword ngxDirective server_names_hash_max_size -syn keyword ngxDirective server_tokens -syn keyword ngxDirective session_log -syn keyword ngxDirective session_log_format -syn keyword ngxDirective session_log_zone -syn keyword ngxDirective set_real_ip_from -syn keyword ngxDirective slice -syn keyword ngxDirective smtp_auth -syn keyword ngxDirective smtp_capabilities -syn keyword ngxDirective smtp_client_buffer -syn keyword ngxDirective smtp_greeting_delay -syn keyword ngxDirective source_charset -syn keyword ngxDirective spdy_chunk_size -syn keyword ngxDirective spdy_headers_comp -syn keyword ngxDirective spdy_keepalive_timeout -syn keyword ngxDirective spdy_max_concurrent_streams -syn keyword ngxDirective spdy_pool_size -syn keyword ngxDirective spdy_recv_buffer_size -syn keyword ngxDirective spdy_recv_timeout -syn keyword ngxDirective spdy_streams_index_size -syn keyword ngxDirective ssi -syn keyword ngxDirective ssi_ignore_recycled_buffers -syn keyword ngxDirective ssi_last_modified -syn keyword ngxDirective ssi_min_file_chunk -syn keyword ngxDirective ssi_silent_errors -syn keyword ngxDirective ssi_types -syn keyword ngxDirective ssi_value_length -syn keyword ngxDirective ssl -syn keyword ngxDirective ssl_buffer_size -syn keyword ngxDirective ssl_certificate -syn keyword ngxDirective ssl_certificate_key -syn keyword ngxDirective ssl_ciphers -syn keyword ngxDirective ssl_client_certificate -syn keyword ngxDirective ssl_crl -syn keyword ngxDirective ssl_dhparam -syn keyword ngxDirective ssl_ecdh_curve -syn keyword ngxDirective ssl_engine -syn keyword ngxDirective ssl_handshake_timeout -syn keyword ngxDirective ssl_password_file -syn keyword ngxDirective ssl_prefer_server_ciphers -syn keyword ngxDirective ssl_preread -syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol skipwhite -syn keyword ngxSSLProtocol SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2 contained nextgroup=ngxSSLProtocol skipwhite -syn keyword ngxDirective ssl_session_cache -syn keyword ngxDirective ssl_session_ticket_key -syn keyword ngxDirective ssl_session_tickets -syn keyword ngxDirective ssl_session_timeout -syn keyword ngxDirective ssl_stapling -syn keyword ngxDirective ssl_stapling_file -syn keyword ngxDirective ssl_stapling_responder -syn keyword ngxDirective ssl_stapling_verify -syn keyword ngxDirective ssl_trusted_certificate -syn keyword ngxDirective ssl_verify_client -syn keyword ngxDirective ssl_verify_depth -syn keyword ngxDirective starttls -syn keyword ngxDirective state -syn keyword ngxDirective status -syn keyword ngxDirective status_format -syn keyword ngxDirective status_zone -syn keyword ngxDirective sticky -syn keyword ngxDirective sticky_cookie_insert -syn keyword ngxDirective stub_status -syn keyword ngxDirective sub_filter -syn keyword ngxDirective sub_filter_last_modified -syn keyword ngxDirective sub_filter_once -syn keyword ngxDirective sub_filter_types -syn keyword ngxDirective tcp_nodelay -syn keyword ngxDirective tcp_nopush -syn keyword ngxDirective thread_pool -syn keyword ngxDirective thread_stack_size -syn keyword ngxDirective timeout -syn keyword ngxDirective timer_resolution -syn keyword ngxDirective types_hash_bucket_size -syn keyword ngxDirective types_hash_max_size -syn keyword ngxDirective underscores_in_headers -syn keyword ngxDirective uninitialized_variable_warn -syn keyword ngxDirective upstream_conf -syn keyword ngxDirective use -syn keyword ngxDirective user -syn keyword ngxDirective userid -syn keyword ngxDirective userid_domain -syn keyword ngxDirective userid_expires -syn keyword ngxDirective userid_mark -syn keyword ngxDirective userid_name -syn keyword ngxDirective userid_p3p -syn keyword ngxDirective userid_path -syn keyword ngxDirective userid_service -syn keyword ngxDirective uwsgi_bind -syn keyword ngxDirective uwsgi_buffer_size -syn keyword ngxDirective uwsgi_buffering -syn keyword ngxDirective uwsgi_buffers -syn keyword ngxDirective uwsgi_busy_buffers_size -syn keyword ngxDirective uwsgi_cache -syn keyword ngxDirective uwsgi_cache_bypass -syn keyword ngxDirective uwsgi_cache_key -syn keyword ngxDirective uwsgi_cache_lock -syn keyword ngxDirective uwsgi_cache_lock_age -syn keyword ngxDirective uwsgi_cache_lock_timeout -syn keyword ngxDirective uwsgi_cache_methods -syn keyword ngxDirective uwsgi_cache_min_uses -syn keyword ngxDirective uwsgi_cache_path -syn keyword ngxDirective uwsgi_cache_purge -syn keyword ngxDirective uwsgi_cache_revalidate -syn keyword ngxDirective uwsgi_cache_use_stale -syn keyword ngxDirective uwsgi_cache_valid -syn keyword ngxDirective uwsgi_connect_timeout -syn keyword ngxDirective uwsgi_force_ranges -syn keyword ngxDirective uwsgi_hide_header -syn keyword ngxDirective uwsgi_ignore_client_abort -syn keyword ngxDirective uwsgi_ignore_headers -syn keyword ngxDirective uwsgi_intercept_errors -syn keyword ngxDirective uwsgi_limit_rate -syn keyword ngxDirective uwsgi_max_temp_file_size -syn keyword ngxDirective uwsgi_modifier1 -syn keyword ngxDirective uwsgi_modifier2 -syn keyword ngxDirective uwsgi_next_upstream -syn keyword ngxDirective uwsgi_next_upstream_timeout -syn keyword ngxDirective uwsgi_next_upstream_tries -syn keyword ngxDirective uwsgi_no_cache -syn keyword ngxDirective uwsgi_param -syn keyword ngxDirective uwsgi_pass -syn keyword ngxDirective uwsgi_pass_header -syn keyword ngxDirective uwsgi_pass_request_body -syn keyword ngxDirective uwsgi_pass_request_headers -syn keyword ngxDirective uwsgi_read_timeout -syn keyword ngxDirective uwsgi_request_buffering -syn keyword ngxDirective uwsgi_send_timeout -syn keyword ngxDirective uwsgi_ssl_certificate -syn keyword ngxDirective uwsgi_ssl_certificate_key -syn keyword ngxDirective uwsgi_ssl_ciphers -syn keyword ngxDirective uwsgi_ssl_crl -syn keyword ngxDirective uwsgi_ssl_name -syn keyword ngxDirective uwsgi_ssl_password_file -syn keyword ngxDirective uwsgi_ssl_protocols nextgroup=ngxSSLProtocol skipwhite -syn keyword ngxDirective uwsgi_ssl_server_name -syn keyword ngxDirective uwsgi_ssl_session_reuse -syn keyword ngxDirective uwsgi_ssl_trusted_certificate -syn keyword ngxDirective uwsgi_ssl_verify -syn keyword ngxDirective uwsgi_ssl_verify_depth -syn keyword ngxDirective uwsgi_store -syn keyword ngxDirective uwsgi_store_access -syn keyword ngxDirective uwsgi_string -syn keyword ngxDirective uwsgi_temp_file_write_size -syn keyword ngxDirective uwsgi_temp_path -syn keyword ngxDirective valid_referers -syn keyword ngxDirective variables_hash_bucket_size -syn keyword ngxDirective variables_hash_max_size -syn keyword ngxDirective worker_aio_requests -syn keyword ngxDirective worker_connections -syn keyword ngxDirective worker_cpu_affinity -syn keyword ngxDirective worker_priority -syn keyword ngxDirective worker_processes -syn keyword ngxDirective worker_rlimit_core -syn keyword ngxDirective worker_rlimit_nofile -syn keyword ngxDirective worker_rlimit_sigpending -syn keyword ngxDirective worker_threads -syn keyword ngxDirective working_directory -syn keyword ngxDirective xclient -syn keyword ngxDirective xml_entities -syn keyword ngxDirective xslt_last_modified -syn keyword ngxDirective xslt_param -syn keyword ngxDirective xslt_string_param -syn keyword ngxDirective xslt_stylesheet -syn keyword ngxDirective xslt_types -syn keyword ngxDirective zone +if has("patch-7.4.1142") + " except control characters, ";", "{", and "}" + syn iskeyword 33-58,60-122,124,126-255 +endif + +syn match ngxName '\([^;{} \t\\]\|\\.\)\+' + \ contains=@ngxDirectives + \ nextgroup=@ngxParams skipwhite skipempty +syn match ngxParam '\([^;{ \t\\]\|\\.\)\+' + \ contained + \ contains=ngxVariable + \ nextgroup=@ngxParams skipwhite skipempty +syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ + \ contains=ngxVariableString + \ nextgroup=@ngxParams skipwhite skipempty +syn match ngxParamComment '#.*$' + \ nextgroup=@ngxParams skipwhite skipempty +syn match ngxSemicolon ';' contained +syn region ngxBlock start=+{+ end=+}+ contained + \ contains=@ngxTopLevel +syn match ngxComment '#.*$' + +syn match ngxVariable '\$\w\+' contained +syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained + +syn cluster ngxTopLevel + \ contains=ngxName,ngxString,ngxComment +syn cluster ngxDirectives + \ contains=ngxDirective,ngxDirectiveBlock,ngxDirectiveImportant + \ add=ngxDirectiveControl,ngxDirectiveError,ngxDirectiveDeprecated + \ add=ngxDirectiveThirdParty +syn cluster ngxParams + \ contains=ngxParam,ngxString,ngxParamComment,ngxSemicolon,ngxBlock + +" boolean parameters + +syn keyword ngxBoolean contained on off + \ nextgroup=@ngxParams skipwhite skipempty +syn cluster ngxParams add=ngxBoolean + +" listen directive + +syn cluster ngxTopLevel add=ngxDirectiveListen +syn keyword ngxDirectiveListen listen + \ nextgroup=@ngxListenParams skipwhite skipempty +syn match ngxListenParam '\([^;{ \t\\]\|\\.\)\+' + \ contained + \ nextgroup=@ngxListenParams skipwhite skipempty +syn region ngxListenString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ + \ contained + \ nextgroup=@ngxListenParams skipwhite skipempty +syn match ngxListenComment '#.*$' + \ contained + \ nextgroup=@ngxListenParams skipwhite skipempty +syn keyword ngxListenOptions contained + \ default_server ssl http2 spdy proxy_protocol + \ setfib fastopen backlog rcvbuf sndbuf accept_filter deferred bind + \ ipv6only reuseport so_keepalive keepidle + \ nextgroup=@ngxListenParams skipwhite skipempty +syn cluster ngxListenParams + \ contains=ngxListenParam,ngxListenString,ngxListenComment + \ add=ngxListenOptions + +syn keyword ngxDirectiveBlock contained http +syn keyword ngxDirectiveBlock contained mail +syn keyword ngxDirectiveBlock contained events +syn keyword ngxDirectiveBlock contained server +syn keyword ngxDirectiveBlock contained types +syn keyword ngxDirectiveBlock contained location +syn keyword ngxDirectiveBlock contained upstream +syn keyword ngxDirectiveBlock contained charset_map +syn keyword ngxDirectiveBlock contained limit_except +syn keyword ngxDirectiveBlock contained if +syn keyword ngxDirectiveBlock contained geo +syn keyword ngxDirectiveBlock contained map +syn keyword ngxDirectiveBlock contained split_clients + +syn keyword ngxDirectiveImportant contained include +syn keyword ngxDirectiveImportant contained root +"syn keyword ngxDirectiveImportant contained server +syn keyword ngxDirectiveImportant contained server_name +"syn keyword ngxDirectiveImportant contained listen +syn keyword ngxDirectiveImportant contained internal +syn keyword ngxDirectiveImportant contained proxy_pass +syn keyword ngxDirectiveImportant contained memcached_pass +syn keyword ngxDirectiveImportant contained fastcgi_pass +syn keyword ngxDirectiveImportant contained scgi_pass +syn keyword ngxDirectiveImportant contained uwsgi_pass +syn keyword ngxDirectiveImportant contained try_files + +syn keyword ngxDirectiveControl contained break +syn keyword ngxDirectiveControl contained return +syn keyword ngxDirectiveControl contained rewrite +syn keyword ngxDirectiveControl contained set + +syn keyword ngxDirectiveError contained error_page +syn keyword ngxDirectiveError contained post_action + +syn keyword ngxDirectiveDeprecated contained connections +syn keyword ngxDirectiveDeprecated contained imap +syn keyword ngxDirectiveDeprecated contained limit_zone +syn keyword ngxDirectiveDeprecated contained mysql_test +syn keyword ngxDirectiveDeprecated contained open_file_cache_retest +syn keyword ngxDirectiveDeprecated contained optimize_server_names +syn keyword ngxDirectiveDeprecated contained satisfy_any +syn keyword ngxDirectiveDeprecated contained so_keepalive + +syn keyword ngxDirective contained absolute_redirect +syn keyword ngxDirective contained accept_mutex +syn keyword ngxDirective contained accept_mutex_delay +syn keyword ngxDirective contained acceptex_read +syn keyword ngxDirective contained access_log +syn keyword ngxDirective contained add_after_body +syn keyword ngxDirective contained add_before_body +syn keyword ngxDirective contained add_header +syn keyword ngxDirective contained addition_types +syn keyword ngxDirective contained aio +syn keyword ngxDirective contained aio_write +syn keyword ngxDirective contained alias +syn keyword ngxDirective contained allow +syn keyword ngxDirective contained ancient_browser +syn keyword ngxDirective contained ancient_browser_value +syn keyword ngxDirective contained auth_basic +syn keyword ngxDirective contained auth_basic_user_file +syn keyword ngxDirective contained auth_http +syn keyword ngxDirective contained auth_http_header +syn keyword ngxDirective contained auth_http_pass_client_cert +syn keyword ngxDirective contained auth_http_timeout +syn keyword ngxDirective contained auth_jwt +syn keyword ngxDirective contained auth_jwt_key_file +syn keyword ngxDirective contained auth_request +syn keyword ngxDirective contained auth_request_set +syn keyword ngxDirective contained autoindex +syn keyword ngxDirective contained autoindex_exact_size +syn keyword ngxDirective contained autoindex_format +syn keyword ngxDirective contained autoindex_localtime +syn keyword ngxDirective contained charset +syn keyword ngxDirective contained charset_map +syn keyword ngxDirective contained charset_types +syn keyword ngxDirective contained chunked_transfer_encoding +syn keyword ngxDirective contained client_body_buffer_size +syn keyword ngxDirective contained client_body_in_file_only +syn keyword ngxDirective contained client_body_in_single_buffer +syn keyword ngxDirective contained client_body_temp_path +syn keyword ngxDirective contained client_body_timeout +syn keyword ngxDirective contained client_header_buffer_size +syn keyword ngxDirective contained client_header_timeout +syn keyword ngxDirective contained client_max_body_size +syn keyword ngxDirective contained connection_pool_size +syn keyword ngxDirective contained create_full_put_path +syn keyword ngxDirective contained daemon +syn keyword ngxDirective contained dav_access +syn keyword ngxDirective contained dav_methods +syn keyword ngxDirective contained debug_connection +syn keyword ngxDirective contained debug_points +syn keyword ngxDirective contained default_type +syn keyword ngxDirective contained degradation +syn keyword ngxDirective contained degrade +syn keyword ngxDirective contained deny +syn keyword ngxDirective contained devpoll_changes +syn keyword ngxDirective contained devpoll_events +syn keyword ngxDirective contained directio +syn keyword ngxDirective contained directio_alignment +syn keyword ngxDirective contained disable_symlinks +syn keyword ngxDirective contained empty_gif +syn keyword ngxDirective contained env +syn keyword ngxDirective contained epoll_events +syn keyword ngxDirective contained error_log +syn keyword ngxDirective contained etag +syn keyword ngxDirective contained eventport_events +syn keyword ngxDirective contained expires +syn keyword ngxDirective contained f4f +syn keyword ngxDirective contained f4f_buffer_size +syn keyword ngxDirective contained fastcgi_bind +syn keyword ngxDirective contained fastcgi_buffer_size +syn keyword ngxDirective contained fastcgi_buffering +syn keyword ngxDirective contained fastcgi_buffers +syn keyword ngxDirective contained fastcgi_busy_buffers_size +syn keyword ngxDirective contained fastcgi_cache +syn keyword ngxDirective contained fastcgi_cache_bypass +syn keyword ngxDirective contained fastcgi_cache_key +syn keyword ngxDirective contained fastcgi_cache_lock +syn keyword ngxDirective contained fastcgi_cache_lock_age +syn keyword ngxDirective contained fastcgi_cache_lock_timeout +syn keyword ngxDirective contained fastcgi_cache_max_range_offset +syn keyword ngxDirective contained fastcgi_cache_methods +syn keyword ngxDirective contained fastcgi_cache_min_uses +syn keyword ngxDirective contained fastcgi_cache_path +syn keyword ngxDirective contained fastcgi_cache_purge +syn keyword ngxDirective contained fastcgi_cache_revalidate +syn keyword ngxDirective contained fastcgi_cache_use_stale +syn keyword ngxDirective contained fastcgi_cache_valid +syn keyword ngxDirective contained fastcgi_catch_stderr +syn keyword ngxDirective contained fastcgi_connect_timeout +syn keyword ngxDirective contained fastcgi_force_ranges +syn keyword ngxDirective contained fastcgi_hide_header +syn keyword ngxDirective contained fastcgi_ignore_client_abort +syn keyword ngxDirective contained fastcgi_ignore_headers +syn keyword ngxDirective contained fastcgi_index +syn keyword ngxDirective contained fastcgi_intercept_errors +syn keyword ngxDirective contained fastcgi_keep_conn +syn keyword ngxDirective contained fastcgi_limit_rate +syn keyword ngxDirective contained fastcgi_max_temp_file_size +syn keyword ngxDirective contained fastcgi_next_upstream +syn keyword ngxDirective contained fastcgi_next_upstream_timeout +syn keyword ngxDirective contained fastcgi_next_upstream_tries +syn keyword ngxDirective contained fastcgi_no_cache +syn keyword ngxDirective contained fastcgi_param +syn keyword ngxDirective contained fastcgi_pass_header +syn keyword ngxDirective contained fastcgi_pass_request_body +syn keyword ngxDirective contained fastcgi_pass_request_headers +syn keyword ngxDirective contained fastcgi_read_timeout +syn keyword ngxDirective contained fastcgi_request_buffering +syn keyword ngxDirective contained fastcgi_send_lowat +syn keyword ngxDirective contained fastcgi_send_timeout +syn keyword ngxDirective contained fastcgi_split_path_info +syn keyword ngxDirective contained fastcgi_store +syn keyword ngxDirective contained fastcgi_store_access +syn keyword ngxDirective contained fastcgi_temp_file_write_size +syn keyword ngxDirective contained fastcgi_temp_path +syn keyword ngxDirective contained flv +syn keyword ngxDirective contained geoip_city +syn keyword ngxDirective contained geoip_country +syn keyword ngxDirective contained geoip_org +syn keyword ngxDirective contained geoip_proxy +syn keyword ngxDirective contained geoip_proxy_recursive +syn keyword ngxDirective contained google_perftools_profiles +syn keyword ngxDirective contained gunzip +syn keyword ngxDirective contained gunzip_buffers +syn keyword ngxDirective contained gzip +syn keyword ngxDirective contained gzip_buffers +syn keyword ngxDirective contained gzip_comp_level +syn keyword ngxDirective contained gzip_disable +syn keyword ngxDirective contained gzip_hash +syn keyword ngxDirective contained gzip_http_version +syn keyword ngxDirective contained gzip_min_length +syn keyword ngxDirective contained gzip_no_buffer +syn keyword ngxDirective contained gzip_proxied +syn keyword ngxDirective contained gzip_static +syn keyword ngxDirective contained gzip_types +syn keyword ngxDirective contained gzip_vary +syn keyword ngxDirective contained gzip_window +syn keyword ngxDirective contained hash +syn keyword ngxDirective contained health_check +syn keyword ngxDirective contained health_check_timeout +syn keyword ngxDirective contained hls +syn keyword ngxDirective contained hls_buffers +syn keyword ngxDirective contained hls_forward_args +syn keyword ngxDirective contained hls_fragment +syn keyword ngxDirective contained hls_mp4_buffer_size +syn keyword ngxDirective contained hls_mp4_max_buffer_size +syn keyword ngxDirective contained http2_chunk_size +syn keyword ngxDirective contained http2_body_preread_size +syn keyword ngxDirective contained http2_idle_timeout +syn keyword ngxDirective contained http2_max_concurrent_streams +syn keyword ngxDirective contained http2_max_field_size +syn keyword ngxDirective contained http2_max_header_size +syn keyword ngxDirective contained http2_max_requests +syn keyword ngxDirective contained http2_recv_buffer_size +syn keyword ngxDirective contained http2_recv_timeout +syn keyword ngxDirective contained if_modified_since +syn keyword ngxDirective contained ignore_invalid_headers +syn keyword ngxDirective contained image_filter +syn keyword ngxDirective contained image_filter_buffer +syn keyword ngxDirective contained image_filter_interlace +syn keyword ngxDirective contained image_filter_jpeg_quality +syn keyword ngxDirective contained image_filter_sharpen +syn keyword ngxDirective contained image_filter_transparency +syn keyword ngxDirective contained image_filter_webp_quality +syn keyword ngxDirective contained imap_auth +syn keyword ngxDirective contained imap_capabilities +syn keyword ngxDirective contained imap_client_buffer +syn keyword ngxDirective contained index +syn keyword ngxDirective contained iocp_threads +syn keyword ngxDirective contained ip_hash +syn keyword ngxDirective contained js_access +syn keyword ngxDirective contained js_content +syn keyword ngxDirective contained js_filter +syn keyword ngxDirective contained js_include +syn keyword ngxDirective contained js_preread +syn keyword ngxDirective contained js_set +syn keyword ngxDirective contained keepalive +syn keyword ngxDirective contained keepalive_disable +syn keyword ngxDirective contained keepalive_requests +syn keyword ngxDirective contained keepalive_timeout +syn keyword ngxDirective contained kqueue_changes +syn keyword ngxDirective contained kqueue_events +syn keyword ngxDirective contained large_client_header_buffers +syn keyword ngxDirective contained least_conn +syn keyword ngxDirective contained least_time +syn keyword ngxDirective contained limit_conn +syn keyword ngxDirective contained limit_conn_log_level +syn keyword ngxDirective contained limit_conn_status +syn keyword ngxDirective contained limit_conn_zone +syn keyword ngxDirective contained limit_rate +syn keyword ngxDirective contained limit_rate_after +syn keyword ngxDirective contained limit_req +syn keyword ngxDirective contained limit_req_log_level +syn keyword ngxDirective contained limit_req_status +syn keyword ngxDirective contained limit_req_zone +syn keyword ngxDirective contained lingering_close +syn keyword ngxDirective contained lingering_time +syn keyword ngxDirective contained lingering_timeout +syn keyword ngxDirective contained load_module +syn keyword ngxDirective contained lock_file +syn keyword ngxDirective contained log_format +syn keyword ngxDirective contained log_not_found +syn keyword ngxDirective contained log_subrequest +syn keyword ngxDirective contained map_hash_bucket_size +syn keyword ngxDirective contained map_hash_max_size +syn keyword ngxDirective contained match +syn keyword ngxDirective contained master_process +syn keyword ngxDirective contained max_ranges +syn keyword ngxDirective contained memcached_bind +syn keyword ngxDirective contained memcached_buffer_size +syn keyword ngxDirective contained memcached_connect_timeout +syn keyword ngxDirective contained memcached_force_ranges +syn keyword ngxDirective contained memcached_gzip_flag +syn keyword ngxDirective contained memcached_next_upstream +syn keyword ngxDirective contained memcached_next_upstream_timeout +syn keyword ngxDirective contained memcached_next_upstream_tries +syn keyword ngxDirective contained memcached_read_timeout +syn keyword ngxDirective contained memcached_send_timeout +syn keyword ngxDirective contained merge_slashes +syn keyword ngxDirective contained min_delete_depth +syn keyword ngxDirective contained modern_browser +syn keyword ngxDirective contained modern_browser_value +syn keyword ngxDirective contained mp4 +syn keyword ngxDirective contained mp4_buffer_size +syn keyword ngxDirective contained mp4_max_buffer_size +syn keyword ngxDirective contained mp4_limit_rate +syn keyword ngxDirective contained mp4_limit_rate_after +syn keyword ngxDirective contained msie_padding +syn keyword ngxDirective contained msie_refresh +syn keyword ngxDirective contained multi_accept +syn keyword ngxDirective contained ntlm +syn keyword ngxDirective contained open_file_cache +syn keyword ngxDirective contained open_file_cache_errors +syn keyword ngxDirective contained open_file_cache_events +syn keyword ngxDirective contained open_file_cache_min_uses +syn keyword ngxDirective contained open_file_cache_valid +syn keyword ngxDirective contained open_log_file_cache +syn keyword ngxDirective contained output_buffers +syn keyword ngxDirective contained override_charset +syn keyword ngxDirective contained pcre_jit +syn keyword ngxDirective contained perl +syn keyword ngxDirective contained perl_modules +syn keyword ngxDirective contained perl_require +syn keyword ngxDirective contained perl_set +syn keyword ngxDirective contained pid +syn keyword ngxDirective contained pop3_auth +syn keyword ngxDirective contained pop3_capabilities +syn keyword ngxDirective contained port_in_redirect +syn keyword ngxDirective contained post_acceptex +syn keyword ngxDirective contained postpone_gzipping From albertcasademont at gmail.com Mon May 22 18:15:43 2017 From: albertcasademont at gmail.com (Albert Casademont) Date: Mon, 22 May 2017 20:15:43 +0200 Subject: Extra RTT on large certificates (again?) Message-ID: Hi, A few years ago a bug was reported on the extra RTT caused by large certificates (https://trac.nginx.org/nginx/ticket/413). Doing some routine testing I see that this behaviour is also present in at least nginx 1.12 and 1.13. Is it possible that the bug has reappeared? The threshold for the extra RTT seems to be again at 4KB Attaching a Webpagetest with the tcpdump file, you can clearly see that the server stops and waits for the extra ACK before sending the remainder of the certificate (the long cert is just for testing, but the same happens when sending the OCSP response if stapling is activated). wpt: https://www.webpagetest.org/result/170522_SA_1A3B tcpdump: https://www.webpagetest.org/getgzip.php?test=170522_SA_1A3B&file=1.cap (use "(ip.addr eq 192.168.10.65 and ip.addr eq 37.187.169.10) and (tcp.port eq 57109 and tcp.port eq 443)" filter in wireshark) Thank you! -------------- next part -------------- An HTML attachment was scrubbed... URL: From Nate.Karstens at garmin.com Mon May 22 19:02:04 2017 From: Nate.Karstens at garmin.com (Karstens, Nate) Date: Mon, 22 May 2017 19:02:04 +0000 Subject: [PATCH] Proxy: support configuration of socket buffer sizes In-Reply-To: <20170519182111.GB55433@mdounin.ru> References: <145451D4E6785E4DA4DFA353A58CB7B2015E152A53@OLAWPA-EXMB04.ad.garmin.com> <145451D4E6785E4DA4DFA353A58CB7B2015E158599@OLAWPA-EXMB04.ad.garmin.com> <20170519182111.GB55433@mdounin.ru> Message-ID: <145451D4E6785E4DA4DFA353A58CB7B2015E1590C0@OLAWPA-EXMB04.ad.garmin.com> Maxim, I'd be happy to explain. Our application is actually relying more on the change to support to SO_SNDBUF option, but I noticed the SO_RCVBUF option there and thought it was worth exposing that at the same time. The application we're having issues with is essentially a file transfer through a proxy to a relatively slow storage medium. Because we're using a proxy there are three buffers involved on the receive end of the HTTP request: 1) receive buffer on external nginx socket, 2) send buffer in nginx proxy module, and 3) receive buffer on proxied server. So, in a system where each buffer is a maximum of 5 MB, you can have 3 x 5 = 15 MB of data in the TCP buffers at a given point in time. In most circumstances, I don't think this would be a problem. However, writing the data is so slow that the HTTP client times out waiting for a reply (which is only sent once all data has been written out). Unfortunately, we cannot solve this by increasing the client's timeout. We found that reducing the size of each buffer -- using the "rcvbuf" parameter to the "listen" directive lets us configure SO_RCVBUF for the first and third sockets mentioned above, and this patch lets us configure SO_SNDBUF of the second socket -- reduces the time between when the client sends the last byte of its request and when it receives a reply, ultimately preventing the timeout. We would prefer not to adjust the system's default sizes for these buffers because that negatively impacts performance on other applications used by the system. Although this seems like a fairly-specific use-case, I think it can be generalized as: 1) the client cannot wait indefinitely after sending the last byte of the request, 2) the server must process all data before it can generate a reply, and 3) the server processes data relatively slowly. This seemed general enough that it was worth adding the functionality for our own use and thought it might be applicable to other users as well. Thanks, Nate -----Original Message----- From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Maxim Dounin Sent: Friday, May 19, 2017 1:21 PM To: nginx-devel at nginx.org Subject: Re: [PATCH] Proxy: support configuration of socket buffer sizes Hello! On Thu, May 18, 2017 at 06:22:41PM +0000, Karstens, Nate wrote: > I just wanted to follow up on this patch and make sure that the fraud > detection notice or confidentiality notice added by my company wasn't > precluding it from consideration. No, it wasn't. And the fraud detection notice seems to be added on your incoming mail, the mailing list copy don't contain anything like this, see http://nginx.org/pipermail/nginx-devel/2017-April/009876.html. Avoiding confidentiality noticies on public mailing lists might be a good idea though. [...] > # HG changeset patch > # User Nate Karstens # Date > 1493467011 18000 > # Sat Apr 29 06:56:51 2017 -0500 > # Node ID 1251a543804b17941b2c96b84bd1f4e58a37bc15 > # Parent 8801ff7d58e1650c9d1abb50e09f5979e4f9ffbf > Proxy: support configuration of socket buffer sizes > > Allows the size of the buffers used by the TCP sockets for HTTP proxy > connections to be configured. The new configuration directives are: > > * proxy_socket_rcvbuf > * proxy_socket_sndbuf > > These correspond with the SO_RCVBUF and SO_SNDBUF socket options, > respectively. > > This is be useful in cases where the proxy processes received data > slowly. Data was being buffered in three separate TCP buffers > (nginx-from-client receive, nginx- to-proxy send, and proxy-from-nginx > receive). The cumulative effect is that the client thinks it has sent > all of the data, but times out waiting for a reply from the proxy, > which cannot reply because it is still processing the data in its > buffers. In practice, we've never seen cases when default socket buffer sizes on backend connections are not appopriate, and/or tuning system default is not sufficient. So even, as you can see from the code, nginx is able to tune SO_RCVBUF in ngx_event_connect_peer(), this was never exposed to configuration. This may be related to the fact that HTTP in general doesn't really depends on particular parts of a request being buffered, and nginx does not use pipelining in requests. Could you please elaborate more on the use case where you see the problem described, and why tuning system defaults is not sufficient in your case? -- Maxim Dounin http://nginx.org/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel ________________________________ CONFIDENTIALITY NOTICE: This email and any attachments are for the sole use of the intended recipient(s) and contain information that may be Garmin confidential and/or Garmin legally privileged. If you have received this email in error, please notify the sender by reply email and delete the message. Any disclosure, copying, distribution or use of this communication (including attachments) by someone other than the intended recipient is prohibited. Thank you. From mdounin at mdounin.ru Mon May 22 19:27:48 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 22 May 2017 22:27:48 +0300 Subject: Extra RTT on large certificates (again?) In-Reply-To: References: Message-ID: <20170522192748.GG55433@mdounin.ru> Hello! On Mon, May 22, 2017 at 08:15:43PM +0200, Albert Casademont wrote: > Hi, > > A few years ago a bug was reported on the extra RTT caused by large > certificates (https://trac.nginx.org/nginx/ticket/413). Doing some routine > testing I see that this behaviour is also present in at least nginx 1.12 > and 1.13. Is it possible that the bug has reappeared? The threshold for the > extra RTT seems to be again at 4KB > > Attaching a Webpagetest with the tcpdump file, you can clearly see that the > server stops and waits for the extra ACK before sending the remainder of > the certificate (the long cert is just for testing, but the same happens > when sending the OCSP response if stapling is activated). > > wpt: https://www.webpagetest.org/result/170522_SA_1A3B > tcpdump: > https://www.webpagetest.org/getgzip.php?test=170522_SA_1A3B&file=1.cap (use > "(ip.addr eq 192.168.10.65 and ip.addr eq 37.187.169.10) and (tcp.port eq > 57109 and tcp.port eq 443)" filter in wireshark) Which OpenSSL version you are using? It is quite possible that changes in OpenSSL broke this, as OpenSSL provides no official way to adjust handshake buffers. Quick testing suggest that it works properly with OpenSSL 1.0.2k, but not with OpenSSL 1.1.0d. Looking into the code suggests that it is broken by this commit: https://github.com/openssl/openssl/commit/2e7dc7cd688 And it looks like it is no longer possible to adjust handshake buffer size with OpenSSL 1.1.0 and up, unfortunately. -- Maxim Dounin http://nginx.org/ From albertcasademont at gmail.com Mon May 22 20:09:38 2017 From: albertcasademont at gmail.com (Albert Casademont) Date: Mon, 22 May 2017 22:09:38 +0200 Subject: Extra RTT on large certificates (again?) In-Reply-To: <20170522192748.GG55433@mdounin.ru> References: <20170522192748.GG55433@mdounin.ru> Message-ID: Hi Maxim, Thanks for the prompt response. Yes, we're using Openssl 1.1.0e at the moment...That is unfortunate, what would you suggest doing? Report this to the openssl devs? An extra RTT is quite painful. Best, Albert On Mon, May 22, 2017 at 9:27 PM, Maxim Dounin wrote: > Hello! > > On Mon, May 22, 2017 at 08:15:43PM +0200, Albert Casademont wrote: > > > Hi, > > > > A few years ago a bug was reported on the extra RTT caused by large > > certificates (https://trac.nginx.org/nginx/ticket/413). Doing some > routine > > testing I see that this behaviour is also present in at least nginx 1.12 > > and 1.13. Is it possible that the bug has reappeared? The threshold for > the > > extra RTT seems to be again at 4KB > > > > Attaching a Webpagetest with the tcpdump file, you can clearly see that > the > > server stops and waits for the extra ACK before sending the remainder of > > the certificate (the long cert is just for testing, but the same happens > > when sending the OCSP response if stapling is activated). > > > > wpt: https://www.webpagetest.org/result/170522_SA_1A3B > > tcpdump: > > https://www.webpagetest.org/getgzip.php?test=170522_SA_1A3B&file=1.cap > (use > > "(ip.addr eq 192.168.10.65 and ip.addr eq 37.187.169.10) and (tcp.port eq > > 57109 and tcp.port eq 443)" filter in wireshark) > > Which OpenSSL version you are using? It is quite possible that > changes in OpenSSL broke this, as OpenSSL provides no official way > to adjust handshake buffers. > > Quick testing suggest that it works properly with OpenSSL 1.0.2k, > but not with OpenSSL 1.1.0d. Looking into the code suggests that > it is broken by this commit: > > https://github.com/openssl/openssl/commit/2e7dc7cd688 > > And it looks like it is no longer possible to adjust handshake > buffer size with OpenSSL 1.1.0 and up, unfortunately. > > -- > 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 albertcasademont at gmail.com Mon May 22 20:34:11 2017 From: albertcasademont at gmail.com (Albert Casademont) Date: Mon, 22 May 2017 22:34:11 +0200 Subject: Extra RTT on large certificates (again?) In-Reply-To: References: <20170522192748.GG55433@mdounin.ru> Message-ID: Seems like the openssl devs are aware of the issue and welcoming PRs, AFAIK nothing's been done yet. https://mta.openssl.org/pipermail/openssl-users/2016-November/004835.html On Mon, May 22, 2017 at 10:09 PM, Albert Casademont < albertcasademont at gmail.com> wrote: > Hi Maxim, > > Thanks for the prompt response. Yes, we're using Openssl 1.1.0e at the > moment...That is unfortunate, what would you suggest doing? Report this to > the openssl devs? An extra RTT is quite painful. > > Best, > > Albert > > On Mon, May 22, 2017 at 9:27 PM, Maxim Dounin wrote: > >> Hello! >> >> On Mon, May 22, 2017 at 08:15:43PM +0200, Albert Casademont wrote: >> >> > Hi, >> > >> > A few years ago a bug was reported on the extra RTT caused by large >> > certificates (https://trac.nginx.org/nginx/ticket/413). Doing some >> routine >> > testing I see that this behaviour is also present in at least nginx 1.12 >> > and 1.13. Is it possible that the bug has reappeared? The threshold for >> the >> > extra RTT seems to be again at 4KB >> > >> > Attaching a Webpagetest with the tcpdump file, you can clearly see that >> the >> > server stops and waits for the extra ACK before sending the remainder of >> > the certificate (the long cert is just for testing, but the same happens >> > when sending the OCSP response if stapling is activated). >> > >> > wpt: https://www.webpagetest.org/result/170522_SA_1A3B >> > tcpdump: >> > https://www.webpagetest.org/getgzip.php?test=170522_SA_1A3B&file=1.cap >> (use >> > "(ip.addr eq 192.168.10.65 and ip.addr eq 37.187.169.10) and (tcp.port >> eq >> > 57109 and tcp.port eq 443)" filter in wireshark) >> >> Which OpenSSL version you are using? It is quite possible that >> changes in OpenSSL broke this, as OpenSSL provides no official way >> to adjust handshake buffers. >> >> Quick testing suggest that it works properly with OpenSSL 1.0.2k, >> but not with OpenSSL 1.1.0d. Looking into the code suggests that >> it is broken by this commit: >> >> https://github.com/openssl/openssl/commit/2e7dc7cd688 >> >> And it looks like it is no longer possible to adjust handshake >> buffer size with OpenSSL 1.1.0 and up, unfortunately. >> >> -- >> 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 mdounin at mdounin.ru Tue May 23 16:02:15 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 23 May 2017 19:02:15 +0300 Subject: Extra RTT on large certificates (again?) In-Reply-To: References: <20170522192748.GG55433@mdounin.ru> Message-ID: <20170523160215.GK55433@mdounin.ru> Hello! On Mon, May 22, 2017 at 10:34:11PM +0200, Albert Casademont wrote: > Seems like the openssl devs are aware of the issue and welcoming PRs, AFAIK > nothing's been done yet. > > https://mta.openssl.org/pipermail/openssl-users/2016-November/004835.html Thanks for the link, it confirms what I already concluded from the code. As mentioned there, quick-and-dirty solution would be recompile OpenSSL with larger buffer size. > > Thanks for the prompt response. Yes, we're using Openssl 1.1.0e at the > > moment...That is unfortunate, what would you suggest doing? Report this to > > the openssl devs? An extra RTT is quite painful. With OpenSSL 1.1.0+ it is no longer possible to adjust handshake buffer size as nginx used to do, and OpenSSL changes are needed to make it possible again. Another approach might be to mitigate extra RTT using TCP_NODELAY. While result will be still non-optimal (as there will be incomplete packets), it should be better than nothing. Patch: # HG changeset patch # User Maxim Dounin # Date 1495555095 -10800 # Tue May 23 18:58:15 2017 +0300 # Node ID 472c23c0a788646403074b359c30c4bbe860cbf6 # Parent 7943298d4ac09aae83ca8eef09bcf0a12c310505 SSL: set TCP_NODELAY on SSL connections earlier. With OpenSSL 1.1.0+, the workaround for handshake buffer size as introduced in a720f0b0e083 (ticket #413) no longer works, as OpenSSL no longer exposes handshake buffers, see https://github.com/openssl/openssl/commit/2e7dc7cd688. Moreover, it no longer possible to adjust handshake buffers at all now. To avoid additional RTT if handshake uses more than 4k we now set TCP_NODELAY on SSL connections before handshake. While this still results in sub-optimal network utilization due to incomplete packets being sent, it seems to be better than nothing. diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -623,14 +623,16 @@ ngx_http_create_request(ngx_connection_t static void ngx_http_ssl_handshake(ngx_event_t *rev) { - u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; - size_t size; - ssize_t n; - ngx_err_t err; - ngx_int_t rc; - ngx_connection_t *c; - ngx_http_connection_t *hc; - ngx_http_ssl_srv_conf_t *sscf; + int tcp_nodelay; + u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; + size_t size; + ssize_t n; + ngx_err_t err; + ngx_int_t rc; + ngx_connection_t *c; + ngx_http_connection_t *hc; + ngx_http_ssl_srv_conf_t *sscf; + ngx_http_core_loc_conf_t *clcf; c = rev->data; hc = c->data; @@ -712,6 +714,36 @@ ngx_http_ssl_handshake(ngx_event_t *rev) ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "https ssl handshake: 0x%02Xd", buf[0]); + clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, + ngx_http_core_module); + + if (clcf->tcp_nodelay + && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); + + tcp_nodelay = 1; + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) + == -1) + { +#if (NGX_SOLARIS) + /* Solaris returns EINVAL if a socket has been shut down */ + c->log_error = NGX_ERROR_IGNORE_EINVAL; +#endif + + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + + c->log_error = NGX_ERROR_INFO; + ngx_http_close_connection(c); + return; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; + } + sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue May 23 16:30:42 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 23 May 2017 19:30:42 +0300 Subject: CXXFLAGS support In-Reply-To: References: Message-ID: <20170523163042.GL55433@mdounin.ru> Hello! On Mon, May 22, 2017 at 01:14:04PM +0300, Sorin Manole wrote: > Missed attachment. > > 2017-05-21 22:23 GMT+03:00 Sorin Manole : > > Hello, > > > > Would you be willing to accept a patch to support CXX and CXXFLAGS in > > the nginx build logic? > > This could be used to write C++ nginx module code. > > I attached a partial implementation. Please confirm if this is the > > correct approach. There are no C++ files in nginx itself except a simple test module which is to test if nginx headers are usable in C++. For this purpose current approach of simply using C compiler and C compiler flags is certainly enough. We may consider something low-intrusive to make writing C++ modules easier. The patch you've provided doesn't look low-intrusive though. Note well that if nginx build process is not enough for you, you may consider using config.make mechanism, which allows generating arbitrary make commands to be used to build your module. -- Maxim Dounin http://nginx.org/ From albertcasademont at gmail.com Tue May 23 16:44:27 2017 From: albertcasademont at gmail.com (Albert Casademont) Date: Tue, 23 May 2017 18:44:27 +0200 Subject: Extra RTT on large certificates (again?) In-Reply-To: <20170523160215.GK55433@mdounin.ru> References: <20170522192748.GG55433@mdounin.ru> <20170523160215.GK55433@mdounin.ru> Message-ID: Hi Maxim, Yes, as we were already compiling our own nginx we apply a patch in openssl before compilation increasing the buffer size to 5120 bytes as a workaround. As for the patch, we already had "tcp_nodelay on" set in our http {} config and we kept seeing the extra RTT, is this a different setting or I am missing something? I believe the optimal solution would be that openssl exposed an API to dynamically adjust the buffer size, I'll try to work on that... Best, Albert On Tue, May 23, 2017 at 6:02 PM, Maxim Dounin wrote: > Hello! > > On Mon, May 22, 2017 at 10:34:11PM +0200, Albert Casademont wrote: > > > Seems like the openssl devs are aware of the issue and welcoming PRs, > AFAIK > > nothing's been done yet. > > > > https://mta.openssl.org/pipermail/openssl-users/2016- > November/004835.html > > Thanks for the link, it confirms what I already concluded from the > code. As mentioned there, quick-and-dirty solution would be > recompile OpenSSL with larger buffer size. > > > > Thanks for the prompt response. Yes, we're using Openssl 1.1.0e at the > > > moment...That is unfortunate, what would you suggest doing? Report > this to > > > the openssl devs? An extra RTT is quite painful. > > With OpenSSL 1.1.0+ it is no longer possible to adjust handshake > buffer size as nginx used to do, and OpenSSL changes are needed to > make it possible again. > > Another approach might be to mitigate extra RTT using TCP_NODELAY. > While result will be still non-optimal (as there will be > incomplete packets), it should be better than nothing. > > Patch: > > # HG changeset patch > # User Maxim Dounin > # Date 1495555095 -10800 > # Tue May 23 18:58:15 2017 +0300 > # Node ID 472c23c0a788646403074b359c30c4bbe860cbf6 > # Parent 7943298d4ac09aae83ca8eef09bcf0a12c310505 > SSL: set TCP_NODELAY on SSL connections earlier. > > With OpenSSL 1.1.0+, the workaround for handshake buffer size as introduced > in a720f0b0e083 (ticket #413) no longer works, as OpenSSL no longer exposes > handshake buffers, see https://github.com/openssl/ > openssl/commit/2e7dc7cd688. > Moreover, it no longer possible to adjust handshake buffers at all now. > > To avoid additional RTT if handshake uses more than 4k we now set > TCP_NODELAY > on SSL connections before handshake. While this still results in > sub-optimal > network utilization due to incomplete packets being sent, it seems to be > better than nothing. > > diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c > --- a/src/http/ngx_http_request.c > +++ b/src/http/ngx_http_request.c > @@ -623,14 +623,16 @@ ngx_http_create_request(ngx_connection_t > static void > ngx_http_ssl_handshake(ngx_event_t *rev) > { > - u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; > - size_t size; > - ssize_t n; > - ngx_err_t err; > - ngx_int_t rc; > - ngx_connection_t *c; > - ngx_http_connection_t *hc; > - ngx_http_ssl_srv_conf_t *sscf; > + int tcp_nodelay; > + u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; > + size_t size; > + ssize_t n; > + ngx_err_t err; > + ngx_int_t rc; > + ngx_connection_t *c; > + ngx_http_connection_t *hc; > + ngx_http_ssl_srv_conf_t *sscf; > + ngx_http_core_loc_conf_t *clcf; > > c = rev->data; > hc = c->data; > @@ -712,6 +714,36 @@ ngx_http_ssl_handshake(ngx_event_t *rev) > ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, > "https ssl handshake: 0x%02Xd", buf[0]); > > + clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, > + ngx_http_core_module); > + > + if (clcf->tcp_nodelay > + && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) > + { > + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, > "tcp_nodelay"); > + > + tcp_nodelay = 1; > + > + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, > + (const void *) &tcp_nodelay, sizeof(int)) > + == -1) > + { > +#if (NGX_SOLARIS) > + /* Solaris returns EINVAL if a socket has been shut > down */ > + c->log_error = NGX_ERROR_IGNORE_EINVAL; > +#endif > + > + ngx_connection_error(c, ngx_socket_errno, > + "setsockopt(TCP_NODELAY) > failed"); > + > + c->log_error = NGX_ERROR_INFO; > + ngx_http_close_connection(c); > + return; > + } > + > + c->tcp_nodelay = NGX_TCP_NODELAY_SET; > + } > + > sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, > ngx_http_ssl_module); > > -- > 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 vbart at nginx.com Tue May 23 17:19:54 2017 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 23 May 2017 17:19:54 +0000 Subject: [nginx] HTTP/2: fixed segfault when memory allocation failed. Message-ID: details: http://hg.nginx.org/nginx/rev/b624fbf7bee2 branches: changeset: 7004:b624fbf7bee2 user: Valentin Bartenev date: Tue May 23 20:19:39 2017 +0300 description: HTTP/2: fixed segfault when memory allocation failed. If allocation of cleanup handler in the HTTP/2 header filter failed, then a stream might be freed with a HEADERS frame left in the output queue. Now the HEADERS frame is accounted in the queue before trying to allocate the cleanup handler. diffstat: src/http/v2/ngx_http_v2_filter_module.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 7943298d4ac0 -r b624fbf7bee2 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Mon May 22 16:34:47 2017 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Tue May 23 20:19:39 2017 +0300 @@ -619,6 +619,8 @@ ngx_http_v2_header_filter(ngx_http_reque ngx_http_v2_queue_blocked_frame(r->stream->connection, frame); + r->stream->queued = 1; + cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { return NGX_ERROR; @@ -627,8 +629,6 @@ ngx_http_v2_header_filter(ngx_http_reque cln->handler = ngx_http_v2_filter_cleanup; cln->data = r->stream; - r->stream->queued = 1; - fc->send_chain = ngx_http_v2_send_chain; fc->need_last_buf = 1; From mdounin at mdounin.ru Tue May 23 17:56:11 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 23 May 2017 20:56:11 +0300 Subject: Extra RTT on large certificates (again?) In-Reply-To: References: <20170522192748.GG55433@mdounin.ru> <20170523160215.GK55433@mdounin.ru> Message-ID: <20170523175611.GM55433@mdounin.ru> Hello! On Tue, May 23, 2017 at 06:44:27PM +0200, Albert Casademont wrote: > Hi Maxim, > > Yes, as we were already compiling our own nginx we apply a patch in openssl > before compilation increasing the buffer size to 5120 bytes as a workaround. > > As for the patch, we already had "tcp_nodelay on" set in our http {} config > and we kept seeing the extra RTT, is this a different setting or I am > missing something? Normally nginx doesn't try to set TCP_NODELAY unless needed, even with "tcp_nodelay on" (which is the default, BTW). Usually it is set when a connection goes to keepalive state. With the patch TCP_NODELAY will be set before SSL handshake, and so there will be no extra RTT if the handshake buffer used by OpenSSL is not enough. > I believe the optimal solution would be that openssl exposed an API to > dynamically adjust the buffer size, I'll try to work on that... Sure. The TCP_NODELAY patch may make sense regardless though, it will address the problem for old OpenSSL versions and will also protect from other similar issues (e.g., we've seen NewSessionTicket messages sent in separate writes when testing TLSv1.3 with OpenSSL master branch). -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue May 23 20:24:33 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 23 May 2017 23:24:33 +0300 Subject: [PATCH] Proxy: support configuration of socket buffer sizes In-Reply-To: <145451D4E6785E4DA4DFA353A58CB7B2015E1590C0@OLAWPA-EXMB04.ad.garmin.com> References: <145451D4E6785E4DA4DFA353A58CB7B2015E152A53@OLAWPA-EXMB04.ad.garmin.com> <145451D4E6785E4DA4DFA353A58CB7B2015E158599@OLAWPA-EXMB04.ad.garmin.com> <20170519182111.GB55433@mdounin.ru> <145451D4E6785E4DA4DFA353A58CB7B2015E1590C0@OLAWPA-EXMB04.ad.garmin.com> Message-ID: <20170523202433.GQ55433@mdounin.ru> Hello! On Mon, May 22, 2017 at 07:02:04PM +0000, Karstens, Nate wrote: > Maxim, > > I'd be happy to explain. Our application is actually relying > more on the change to support to SO_SNDBUF option, but I noticed > the SO_RCVBUF option there and thought it was worth exposing > that at the same time. > > The application we're having issues with is essentially a file > transfer through a proxy to a relatively slow storage medium. > Because we're using a proxy there are three buffers involved on > the receive end of the HTTP request: 1) receive buffer on > external nginx socket, 2) send buffer in nginx proxy module, and > 3) receive buffer on proxied server. So, in a system where each > buffer is a maximum of 5 MB, you can have 3 x 5 = 15 MB of data > in the TCP buffers at a given point in time. Send buffer on the client contributes to overral buffering as well, and probably should be counted too. But, frankly, 5MB is a lot, and much higher than typical default, and may result in problems by itself. See https://blog.cloudflare.com/the-curious-case-of-slow-downloads/ for a description of a problem Cloudflare faced with such socket buffer sizes. > In most circumstances, I don't think this would be a problem. > However, writing the data is so slow that the HTTP client times > out waiting for a reply (which is only sent once all data has > been written out). Unfortunately, we cannot solve this by > increasing the client's timeout. We found that reducing the size Are you using some custom client, or a browser? Even with buffers as huge as 3x5MB, a really slow backend will be required to trigger a timeout in a typical browser, as browsers seems to happily wait for 60+ seconds (actually, much more, but 60 seconds is a default timeout in nginx). This means that backend needs to be slower than 250 KB/seconds for this to become a problem even without any socket tuning, and this sounds more like an 1x CD than even a class 2 SD-card. > of each buffer -- using the "rcvbuf" parameter to the "listen" > directive lets us configure SO_RCVBUF for the first and third > sockets mentioned above, and this patch lets us configure > SO_SNDBUF of the second socket -- reduces the time between when > the client sends the last byte of its request and when it > receives a reply, ultimately preventing the timeout. We would > prefer not to adjust the system's default sizes for these > buffers because that negatively impacts performance on other > applications used by the system. > > Although this seems like a fairly-specific use-case, I think it > can be generalized as: 1) the client cannot wait indefinitely > after sending the last byte of the request, 2) the server must > process all data before it can generate a reply, and 3) the > server processes data relatively slowly. This seemed general > enough that it was worth adding the functionality for our own > use and thought it might be applicable to other users as well. Normally, nginx reads the whole request from the client, and only after that starts sending it to a backend server. This effectively means infinite buffering, and certainly will trigger a timeout if the backend server is not able to process the request in a reasonable time. Socket buffer sizes may become important when using "proxy_request_buffering off" and/or non-http connections (e.g., WebSocket ones), but these are specific by itself. Overall, thank you for the patch, but it looks like something very specific for your particular use case. We would like to avoid introducing this into nginx, at least till there are more requests for this. I would also recommend to take a closer look at your setup. Numbers you've provided suggest that there may be something wrong elsewhere, and the fact that smaller buffers fix the problem may be unrelated. -- Maxim Dounin http://nginx.org/ From albertcasademont at gmail.com Tue May 23 21:21:32 2017 From: albertcasademont at gmail.com (Albert Casademont) Date: Tue, 23 May 2017 23:21:32 +0200 Subject: Extra RTT on large certificates (again?) In-Reply-To: <20170523175611.GM55433@mdounin.ru> References: <20170522192748.GG55433@mdounin.ru> <20170523160215.GK55433@mdounin.ru> <20170523175611.GM55433@mdounin.ru> Message-ID: Thanks, makes perfect sense :) On Tue, May 23, 2017 at 7:56 PM, Maxim Dounin wrote: > Hello! > > On Tue, May 23, 2017 at 06:44:27PM +0200, Albert Casademont wrote: > > > Hi Maxim, > > > > Yes, as we were already compiling our own nginx we apply a patch in > openssl > > before compilation increasing the buffer size to 5120 bytes as a > workaround. > > > > As for the patch, we already had "tcp_nodelay on" set in our http {} > config > > and we kept seeing the extra RTT, is this a different setting or I am > > missing something? > > Normally nginx doesn't try to set TCP_NODELAY unless needed, even > with "tcp_nodelay on" (which is the default, BTW). Usually > it is set when a connection goes to keepalive state. > > With the patch TCP_NODELAY will be set before SSL handshake, and > so there will be no extra RTT if the handshake buffer used by > OpenSSL is not enough. > > > I believe the optimal solution would be that openssl exposed an API to > > dynamically adjust the buffer size, I'll try to work on that... > > Sure. > > The TCP_NODELAY patch may make sense regardless though, it will > address the problem for old OpenSSL versions and will also protect > from other similar issues (e.g., we've seen NewSessionTicket > messages sent in separate writes when testing TLSv1.3 with OpenSSL > master branch). > > -- > 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 arut at nginx.com Wed May 24 10:19:01 2017 From: arut at nginx.com (Roman Arutyunyan) Date: Wed, 24 May 2017 10:19:01 +0000 Subject: [nginx] Fixed deferred accept with EPOLLRDHUP enabled (ticket #1278). Message-ID: details: http://hg.nginx.org/nginx/rev/3e2d90073adf branches: changeset: 7005:3e2d90073adf user: Roman Arutyunyan date: Wed May 24 13:17:08 2017 +0300 description: Fixed deferred accept with EPOLLRDHUP enabled (ticket #1278). Previously, the read event of the accepted connection was marked ready, but not available. This made EPOLLRDHUP-related code (for example, in ngx_unix_recv()) expect more data from the socket, leading to unexpected behavior. For example, if SSL, PROXY protocol and deferred accept were enabled on a listen socket, the client connection was aborted due to unexpected return value of c->recv(). diffstat: src/event/ngx_event_accept.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r b624fbf7bee2 -r 3e2d90073adf src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c Tue May 23 20:19:39 2017 +0300 +++ b/src/event/ngx_event_accept.c Wed May 24 13:17:08 2017 +0300 @@ -238,7 +238,7 @@ ngx_event_accept(ngx_event_t *ev) if (ev->deferred_accept) { rev->ready = 1; -#if (NGX_HAVE_KQUEUE) +#if (NGX_HAVE_KQUEUE || NGX_HAVE_EPOLLRDHUP) rev->available = 1; #endif } From vbart at nginx.com Wed May 24 16:49:17 2017 From: vbart at nginx.com (Valentin V. Bartenev) Date: Wed, 24 May 2017 19:49:17 +0300 Subject: [PATCH] HTTP/2: add debug logging of pseudo-headers and cookies In-Reply-To: <164b95f24f414359c5b8.1493074726@piotrsikora.sfo.corp.google.com> References: <2626325.vZ0dWXWuNK@vbart-workstation> <164b95f24f414359c5b8.1493074726@piotrsikora.sfo.corp.google.com> Message-ID: <3433727.YHEi7QJnSm@vbart-workstation> On Monday 24 April 2017 15:58:46 Piotr Sikora via nginx-devel wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1490516711 25200 > # Sun Mar 26 01:25:11 2017 -0700 > # Node ID 164b95f24f414359c5b8045415da3de82653c4db > # Parent 2c4dbcd6f2e4c9c2a1eb8dc1f0d39c99975ae208 > HTTP/2: add debug logging of pseudo-headers and cookies. > > Signed-off-by: Piotr Sikora > > diff -r 2c4dbcd6f2e4 -r 164b95f24f41 src/http/v2/ngx_http_v2.c > --- a/src/http/v2/ngx_http_v2.c > +++ b/src/http/v2/ngx_http_v2.c > @@ -1589,6 +1589,10 @@ ngx_http_v2_state_process_header(ngx_htt > rc = ngx_http_v2_pseudo_header(r, header); > > if (rc == NGX_OK) { > + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, > + "http2 pseudo-header: \":%V: %V\"", > + &header->name, &header->value); > + > return ngx_http_v2_state_header_complete(h2c, pos, end); > } > > @@ -1630,6 +1634,10 @@ ngx_http_v2_state_process_header(ngx_htt > NGX_HTTP_V2_INTERNAL_ERROR); > } > > + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, > + "http2 http header: \"%V: %V\"", > + &header->name, &header->value); > + > return ngx_http_v2_state_header_complete(h2c, pos, end); > } > > IMHO, it's better to not duplicate message for Cookie: # HG changeset patch # User Piotr Sikora # Date 1490516711 25200 # Sun Mar 26 01:25:11 2017 -0700 # Node ID 9e5113f051206b2c09a377ac524c33f33ba0602a # Parent b624fbf7bee296b8f95f4a90228a1920127f12a0 HTTP/2: add debug logging of pseudo-headers and cookies. Signed-off-by: Piotr Sikora diff -r b624fbf7bee2 -r 9e5113f05120 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue May 23 20:19:39 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Sun Mar 26 01:25:11 2017 -0700 @@ -1589,6 +1589,10 @@ ngx_http_v2_state_process_header(ngx_htt rc = ngx_http_v2_pseudo_header(r, header); if (rc == NGX_OK) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http2 pseudo-header: \":%V: %V\"", + &header->name, &header->value); + return ngx_http_v2_state_header_complete(h2c, pos, end); } @@ -1630,36 +1634,39 @@ ngx_http_v2_state_process_header(ngx_htt NGX_HTTP_V2_INTERNAL_ERROR); } - return ngx_http_v2_state_header_complete(h2c, pos, end); - } - - h = ngx_list_push(&r->headers_in.headers); - if (h == NULL) { - return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); - } - - h->key.len = header->name.len; - h->key.data = header->name.data; - - /* TODO Optimization: precalculate hash and handler for indexed headers. */ - h->hash = ngx_hash_key(h->key.data, h->key.len); - - h->value.len = header->value.len; - h->value.data = header->value.data; - - h->lowcase_key = h->key.data; - - cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - - hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, - h->lowcase_key, h->key.len); - - if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - goto error; + } else { + h = ngx_list_push(&r->headers_in.headers); + if (h == NULL) { + return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); + } + + h->key.len = header->name.len; + h->key.data = header->name.data; + + /* + * TODO Optimization: precalculate hash + * and handler for indexed headers. + */ + h->hash = ngx_hash_key(h->key.data, h->key.len); + + h->value.len = header->value.len; + h->value.data = header->value.data; + + h->lowcase_key = h->key.data; + + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + + hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, + h->lowcase_key, h->key.len); + + if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { + goto error; + } } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http2 http header: \"%V: %V\"", &h->key, &h->value); + "http2 http header: \"%V: %V\"", + &header->name, &header->value); return ngx_http_v2_state_header_complete(h2c, pos, end); From ranier.vf at gmail.com Wed May 24 19:01:25 2017 From: ranier.vf at gmail.com (Ranier Vf) Date: Wed, 24 May 2017 16:01:25 -0300 Subject: Nginx with Postgresql Message-ID: Hi, Anybody knows what is correct place to call Postgresql PQconnectdb? I writing a module with Postgresql integration and get segmentation fault, when calls PQfinish and PQclear. Is init_master? What module place is correct to: 1. create module vars to pgres connection? 2. make connection with postgresql (PQconnectdb)? 3. handle cleanup with PQfinish? Best regards, Ranier Vilela Livre de v?rus. www.avast.com . <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Thu May 25 08:57:56 2017 From: igor at sysoev.ru (Igor Sysoev) Date: Thu, 25 May 2017 11:57:56 +0300 Subject: [njs] Lexer support for hexadecimal literal values. In-Reply-To: References: Message-ID: <6174F1B3-E0BB-4818-BC96-5965255FD1F4@sysoev.ru> Thank you for your patch. We are currently working on comprehensive hexadecimal support. -- Igor Sysoev http://nginx.com On 21 May 2017, at 20:52, Paulo Pacheco wrote: > # HG changeset patch > # User Paulo Pacheco > # Date 1495388206 0 > # Sun May 21 17:36:46 2017 +0000 > # Node ID 22db6b6a3a0eebff8453fb22035628410c05c5c8 > # Parent 96fda9957427e1ea78d0096b019a3f3183db7346 > [njs] Lexer support for hexadecimal literal values. > > diff -r 96fda9957427 -r 22db6b6a3a0e njs/njs_lexer.c > --- a/njs/njs_lexer.c Wed Apr 19 17:48:56 2017 +0300 > +++ b/njs/njs_lexer.c Sun May 21 17:36:46 2017 +0000 > @@ -19,7 +19,7 @@ > #include > #include > #include > - > +#include > > typedef struct njs_lexer_multi_s njs_lexer_multi_t; > > @@ -539,10 +539,28 @@ > { > u_char c, *p; > double num, frac, scale; > + char *endptr; > > /* TODO: "1e2" */ > > p = lexer->start; > + > + /* Hexadecimal literal values */ > + if ( (lexer->end - lexer->start) > 2 > + && (*p == 'x' || *p == 'X') > + && (lexer->prev_token > 0 > + || ((lexer->start - 1) == lexer->text.start) > + ) > + && (*(p-1) == '0')) { > + > + lexer->number = strtod((const char *) p-1, &endptr); > + if ((u_char *) endptr <= lexer->end) { > + lexer->start = (u_char *) endptr; > + return NJS_TOKEN_NUMBER; > + } > + lexer->number = 0; > + } > + > c = p[-1]; > > /* Values below '0' become >= 208. */ > diff -r 96fda9957427 -r 22db6b6a3a0e njs/test/njs_unit_test.c > --- a/njs/test/njs_unit_test.c Wed Apr 19 17:48:56 2017 +0300 > +++ b/njs/test/njs_unit_test.c Sun May 21 17:36:46 2017 +0000 > @@ -112,6 +112,18 @@ > { nxt_string("+1"), > nxt_string("1") }, > > + { nxt_string("var a = 0x01; a"), > + nxt_string("1") }, > + > + { nxt_string("var x = 0xffff; x"), > + nxt_string("65535") }, > + > + { nxt_string("0x01"), > + nxt_string("1") }, > + > + { nxt_string("0xffff"), > + nxt_string("65535") }, > + > { nxt_string("+1\n"), > nxt_string("1") }, > > > ---------------------------------- CUT HERE -------------------------------------- > Paulo Pacheco | ????? ?????? > > > _______________________________________________ > 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 xeioex at nginx.com Thu May 25 11:39:59 2017 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Thu, 25 May 2017 11:39:59 +0000 Subject: [njs] parseInt() fixed for hexadecimal literals. Message-ID: details: http://hg.nginx.org/njs/rev/fc6c8da00858 branches: changeset: 341:fc6c8da00858 user: Dmitry Volyntsev date: Thu May 25 14:16:31 2017 +0300 description: parseInt() fixed for hexadecimal literals. diffstat: njs/njs_number.c | 33 +++++++++++++++++++-------------- njs/test/njs_unit_test.c | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 14 deletions(-) diffs (87 lines): diff -r 96fda9957427 -r fc6c8da00858 njs/njs_number.c --- a/njs/njs_number.c Wed Apr 19 17:48:56 2017 +0300 +++ b/njs/njs_number.c Thu May 25 14:16:31 2017 +0300 @@ -662,7 +662,7 @@ njs_number_parse_int(njs_vm_t *vm, njs_v u_char *p, *end; int64_t n; uint8_t radix; - nxt_bool_t minus; + nxt_bool_t minus, test_prefix; njs_string_prop_t string; num = NAN; @@ -693,25 +693,30 @@ njs_number_parse_int(njs_vm_t *vm, njs_v p++; } - if (end - p > 1 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { - p += 2; - radix = 16; + test_prefix = (end - p > 1); + + if (nargs > 2) { + radix = args[2].data.u.number; + + if (radix < 2 || radix > 36) { + goto done; + } + + if (radix != 16) { + test_prefix = 0; + } } else { radix = 10; } - if (nargs > 2) { - n = args[2].data.u.number; - - if (n != 0) { + if (test_prefix && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { + p += 2; + radix = 16; + } - if (n < 2 || n > 36) { - goto done; - } - - radix = n; - } + if (p == end) { + goto done; } n = njs_number_radix_parse(p, end, radix, 0); diff -r 96fda9957427 -r fc6c8da00858 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Apr 19 17:48:56 2017 +0300 +++ b/njs/test/njs_unit_test.c Thu May 25 14:16:31 2017 +0300 @@ -7047,6 +7047,27 @@ static njs_unit_test_t njs_test[] = { nxt_string("parseInt('njscript', 36)"), nxt_string("1845449130881") }, + { nxt_string("parseInt('0x')"), + nxt_string("NaN") }, + + { nxt_string("parseInt('0x', 10)"), + nxt_string("0") }, + + { nxt_string("parseInt('0x', 16)"), + nxt_string("NaN") }, + + { nxt_string("parseInt('0x', 33)"), + nxt_string("0") }, + + { nxt_string("parseInt('0x', 34)"), + nxt_string("33") }, + + { nxt_string("parseInt('0', 1)"), + nxt_string("NaN") }, + + { nxt_string("parseInt('0', 37)"), + nxt_string("NaN") }, + { nxt_string("parseFloat('12345abc')"), nxt_string("12345") }, From arut at nginx.com Thu May 25 15:18:52 2017 From: arut at nginx.com (Roman Arutyunyan) Date: Thu, 25 May 2017 15:18:52 +0000 Subject: [nginx] Background subrequests for cache updates. Message-ID: details: http://hg.nginx.org/nginx/rev/9552758a786e branches: changeset: 7006:9552758a786e user: Roman Arutyunyan date: Thu May 25 15:57:59 2017 +0300 description: Background subrequests for cache updates. Previously, cache background update might not work as expected, making client wait for it to complete before receiving the final part of a stale response. This could happen if the response could not be sent to the client socket in one filter chain call. Now background cache update is done in a background subrequest. This type of subrequest does not block any other subrequests or the main request. diffstat: src/http/ngx_http_core_module.c | 41 ++++++++++++++++++++++------------------- src/http/ngx_http_request.c | 27 ++++++++++++++++++++++++--- src/http/ngx_http_request.h | 3 ++- src/http/ngx_http_upstream.c | 8 ++++---- 4 files changed, 52 insertions(+), 27 deletions(-) diffs (185 lines): diff -r 3e2d90073adf -r 9552758a786e src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Wed May 24 13:17:08 2017 +0300 +++ b/src/http/ngx_http_core_module.c Thu May 25 15:57:59 2017 +0300 @@ -2518,6 +2518,7 @@ ngx_http_subrequest(ngx_http_request_t * sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0; sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0; + sr->background = (flags & NGX_HTTP_SUBREQUEST_BACKGROUND) != 0; sr->unparsed_uri = r->unparsed_uri; sr->method_name = ngx_http_core_get_method; @@ -2531,29 +2532,31 @@ ngx_http_subrequest(ngx_http_request_t * sr->read_event_handler = ngx_http_request_empty_handler; sr->write_event_handler = ngx_http_handler; - if (c->data == r && r->postponed == NULL) { - c->data = sr; - } - sr->variables = r->variables; sr->log_handler = r->log_handler; - pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t)); - if (pr == NULL) { - return NGX_ERROR; - } - - pr->request = sr; - pr->out = NULL; - pr->next = NULL; - - if (r->postponed) { - for (p = r->postponed; p->next; p = p->next) { /* void */ } - p->next = pr; - - } else { - r->postponed = pr; + if (!sr->background) { + if (c->data == r && r->postponed == NULL) { + c->data = sr; + } + + pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t)); + if (pr == NULL) { + return NGX_ERROR; + } + + pr->request = sr; + pr->out = NULL; + pr->next = NULL; + + if (r->postponed) { + for (p = r->postponed; p->next; p = p->next) { /* void */ } + p->next = pr; + + } else { + r->postponed = pr; + } } sr->internal = 1; diff -r 3e2d90073adf -r 9552758a786e src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Wed May 24 13:17:08 2017 +0300 +++ b/src/http/ngx_http_request.c Thu May 25 15:57:59 2017 +0300 @@ -2357,6 +2357,26 @@ ngx_http_finalize_request(ngx_http_reque } if (r != r->main) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (r->background) { + if (!r->logged) { + if (clcf->log_subrequest) { + ngx_http_log_request(r); + } + + r->logged = 1; + + } else { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "subrequest: \"%V?%V\" logged again", + &r->uri, &r->args); + } + + r->done = 1; + ngx_http_finalize_connection(r); + return; + } if (r->buffered || r->postponed) { @@ -2374,9 +2394,6 @@ ngx_http_finalize_request(ngx_http_reque r->main->count--; if (!r->logged) { - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (clcf->log_subrequest) { ngx_http_log_request(r); } @@ -2440,6 +2457,8 @@ ngx_http_finalize_request(ngx_http_reque } r->done = 1; + + r->read_event_handler = ngx_http_block_reading; r->write_event_handler = ngx_http_request_empty_handler; if (!r->post_action) { @@ -2558,6 +2577,8 @@ ngx_http_finalize_connection(ngx_http_re return; } + r = r->main; + if (r->reading_body) { r->keepalive = 0; r->lingering_close = 1; diff -r 3e2d90073adf -r 9552758a786e src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Wed May 24 13:17:08 2017 +0300 +++ b/src/http/ngx_http_request.h Thu May 25 15:57:59 2017 +0300 @@ -64,6 +64,7 @@ #define NGX_HTTP_SUBREQUEST_IN_MEMORY 2 #define NGX_HTTP_SUBREQUEST_WAITED 4 #define NGX_HTTP_SUBREQUEST_CLONE 8 +#define NGX_HTTP_SUBREQUEST_BACKGROUND 16 #define NGX_HTTP_LOG_UNSAFE 1 @@ -486,7 +487,6 @@ struct ngx_http_request_s { #if (NGX_HTTP_CACHE) unsigned cached:1; - unsigned cache_updater:1; #endif #if (NGX_HTTP_GZIP) @@ -543,6 +543,7 @@ struct ngx_http_request_s { unsigned stat_writing:1; unsigned stat_processing:1; + unsigned background:1; unsigned health_check:1; /* used to parse HTTP headers */ diff -r 3e2d90073adf -r 9552758a786e src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Wed May 24 13:17:08 2017 +0300 +++ b/src/http/ngx_http_upstream.c Thu May 25 15:57:59 2017 +0300 @@ -879,7 +879,7 @@ ngx_http_upstream_cache(ngx_http_request case NGX_HTTP_CACHE_STALE: if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) - || c->stale_updating) && !r->cache_updater + || c->stale_updating) && !r->background && u->conf->cache_background_update) { r->cache->background = 1; @@ -892,7 +892,7 @@ ngx_http_upstream_cache(ngx_http_request case NGX_HTTP_CACHE_UPDATING: if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) - || c->stale_updating) && !r->cache_updater) + || c->stale_updating) && !r->background) { u->cache_status = rc; rc = NGX_OK; @@ -1076,14 +1076,14 @@ ngx_http_upstream_cache_background_updat } if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL, - NGX_HTTP_SUBREQUEST_CLONE) + NGX_HTTP_SUBREQUEST_CLONE + |NGX_HTTP_SUBREQUEST_BACKGROUND) != NGX_OK) { return NGX_ERROR; } sr->header_only = 1; - sr->cache_updater = 1; return NGX_OK; } From sepherosa at gmail.com Fri May 26 03:20:01 2017 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Fri, 26 May 2017 11:20:01 +0800 Subject: [PATCH] Add RFC5424 syslog support In-Reply-To: References: Message-ID: Hi all, Any update on this? Thanks, sephe On Thu, Apr 20, 2017 at 3:40 PM, Sepherosa Ziehau wrote: > RFC5424: https://tools.ietf.org/html/rfc5424 > > The main point is the support of RFC5424's "STRUCTURED-DATA". > > Patch is here: > https://leaf.dragonflybsd.org/~sephe/nginx_rfc5424.diff > > Thanks, > sephe > > -- > Tomorrow Will Never Die -- Tomorrow Will Never Die From vl at nginx.com Fri May 26 05:35:45 2017 From: vl at nginx.com (Vladimir Homutov) Date: Fri, 26 May 2017 08:35:45 +0300 Subject: [PATCH] Add RFC5424 syslog support In-Reply-To: References: Message-ID: <20170526053544.GA17314@vlpc> On Fri, May 26, 2017 at 11:20:01AM +0800, Sepherosa Ziehau wrote: > Hi all, > > Any update on this? > Hi, nginx deliberately supports just RFC 3164 and not any later version to keep things simple. supporting just parts of later standard seems quite strange and misleading to me. From sepherosa at gmail.com Fri May 26 06:54:10 2017 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Fri, 26 May 2017 14:54:10 +0800 Subject: [PATCH] Add RFC5424 syslog support In-Reply-To: <20170526053544.GA17314@vlpc> References: <20170526053544.GA17314@vlpc> Message-ID: On Fri, May 26, 2017 at 1:35 PM, Vladimir Homutov wrote: > On Fri, May 26, 2017 at 11:20:01AM +0800, Sepherosa Ziehau wrote: >> Hi all, >> >> Any update on this? >> > Hi, > > nginx deliberately supports just RFC 3164 and not any later version to keep > things simple. Thank you for the information. I will drop it then. > > supporting just parts of later standard seems quite strange and misleading to > me. Well, it's actually full support. Thanks, sephe -- Tomorrow Will Never Die From sepherosa at gmail.com Fri May 26 06:56:06 2017 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Fri, 26 May 2017 14:56:06 +0800 Subject: [PATCH] worker_cpu_affinity support for DragonFlyBSD Message-ID: Hi all, The patch is here: https://leaf.dragonflybsd.org/~sephe/nginx_dfly_affinity.diff Unlike FreeBSD, we adopted sched_setaffinity() syscall for process CPU affinity. Thanks, sephe -- Tomorrow Will Never Die From sepherosa at gmail.com Fri May 26 08:42:51 2017 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Fri, 26 May 2017 16:42:51 +0800 Subject: [PATCH] Be more verbose in ngx_setaffinity() Message-ID: Hi all, Patch is here: https://leaf.dragonflybsd.org/~sephe/verb_setaffinity.diff Thanks, sephe -- Tomorrow Will Never Die From jeppojeps at gmail.com Fri May 26 10:03:14 2017 From: jeppojeps at gmail.com (Antonio Nappa) Date: Fri, 26 May 2017 12:03:14 +0200 Subject: PREACCESS CTX is NULL Message-ID: Hello, I am allocating a ctx (on r->connection->pool) during the POST_READ phase, and I find out that in PREACCESS the ctx is NULL, is this an intended behavior? Thanks, Jeppo -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Fri May 26 15:31:41 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 26 May 2017 18:31:41 +0300 Subject: [PATCH] Be more verbose in ngx_setaffinity() In-Reply-To: References: Message-ID: <20170526153141.GF55433@mdounin.ru> Hello! On Fri, May 26, 2017 at 04:42:51PM +0800, Sepherosa Ziehau wrote: > Hi all, > > Patch is here: > https://leaf.dragonflybsd.org/~sephe/verb_setaffinity.diff Process PID is present in error log messages, it is believed to be enough to identify which worker uses which CPU. It is also looks like a layering violation to print ngx_worker from a generic function which knows nothing if it is being called in a worker process or not. Do you have any specific reasons for the change? -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Fri May 26 16:04:01 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 26 May 2017 19:04:01 +0300 Subject: [PATCH] worker_cpu_affinity support for DragonFlyBSD In-Reply-To: References: Message-ID: <20170526160401.GG55433@mdounin.ru> Hello! On Fri, May 26, 2017 at 02:56:06PM +0800, Sepherosa Ziehau wrote: > Hi all, > > The patch is here: > https://leaf.dragonflybsd.org/~sephe/nginx_dfly_affinity.diff > > Unlike FreeBSD, we adopted sched_setaffinity() syscall for process CPU affinity. A better solution might be to move sched_setaffinity() test from auto/os/linux to auto/unix instead. Patch below (untested). # HG changeset patch # User Maxim Dounin # Date 1495814031 -10800 # Fri May 26 18:53:51 2017 +0300 # Node ID d4d316c4503f7b9bbf47b0006822e4438e6e641a # Parent 9552758a786e20c70130427298895bc782a754c5 Configure: sched_setaffinity() test moved to auto/unix. The sched_setaffinity() function was introduced in DragonFly BSD 4.7, so it is no longer Linux-specific. diff --git a/auto/os/linux b/auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -157,20 +157,6 @@ ngx_feature_test="if (prctl(PR_SET_DUMPA . auto/feature -# sched_setaffinity() - -ngx_feature="sched_setaffinity()" -ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="cpu_set_t mask; - CPU_ZERO(&mask); - sched_setaffinity(0, sizeof(cpu_set_t), &mask)" -. auto/feature - - # crypt_r() ngx_feature="crypt_r()" diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -300,6 +300,18 @@ if [ $ngx_found = no ]; then fi +ngx_feature="sched_setaffinity()" +ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" +ngx_feature_run=no +ngx_feature_incs="#include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="cpu_set_t mask; + CPU_ZERO(&mask); + sched_setaffinity(0, sizeof(cpu_set_t), &mask)" +. auto/feature + + ngx_feature="SO_SETFIB" ngx_feature_name="NGX_HAVE_SETFIB" ngx_feature_run=no -- Maxim Dounin http://nginx.org/ From igor at sysoev.ru Fri May 26 17:14:30 2017 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 26 May 2017 17:14:30 +0000 Subject: [njs] parseInt() did not test invalid values. Message-ID: details: http://hg.nginx.org/njs/rev/be8d68d4b8b5 branches: changeset: 342:be8d68d4b8b5 user: Igor Sysoev date: Fri May 26 20:07:24 2017 +0300 description: parseInt() did not test invalid values. diffstat: njs/njs_number.c | 22 ++++++++++++---------- njs/njs_number.h | 3 +-- njs/njs_parser.c | 7 ++++--- njs/test/njs_unit_test.c | 10 ++++++++-- 4 files changed, 25 insertions(+), 17 deletions(-) diffs (117 lines): diff -r fc6c8da00858 -r be8d68d4b8b5 njs/njs_number.c --- a/njs/njs_number.c Thu May 25 14:16:31 2017 +0300 +++ b/njs/njs_number.c Fri May 26 20:07:24 2017 +0300 @@ -132,9 +132,11 @@ njs_number_parse(const u_char **start, c int64_t -njs_number_radix_parse(u_char *p, u_char *end, uint8_t radix, nxt_bool_t exact) +njs_number_radix_parse(u_char **start, u_char *end, uint8_t radix) { + u_char *p; uint8_t d; + int64_t num; uint64_t n; static const int8_t digits[256] @@ -158,19 +160,23 @@ njs_number_radix_parse(u_char *p, u_char -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; + num = -1; n = 0; - while (p < end) { - d = digits[*p++]; + for (p = *start; p < end; p++) { + d = digits[*p]; if (nxt_slow_path(d >= radix)) { - return (exact) ? -1 : (int64_t) n; + break; } n = (n * radix) + d; + num = n; } - return n; + *start = p; + + return num; } @@ -715,11 +721,7 @@ njs_number_parse_int(njs_vm_t *vm, njs_v radix = 16; } - if (p == end) { - goto done; - } - - n = njs_number_radix_parse(p, end, radix, 0); + n = njs_number_radix_parse(&p, end, radix); if (n >= 0) { num = (minus) ? -n : n; diff -r fc6c8da00858 -r be8d68d4b8b5 njs/njs_number.h --- a/njs/njs_number.h Thu May 25 14:16:31 2017 +0300 +++ b/njs/njs_number.h Fri May 26 20:07:24 2017 +0300 @@ -13,8 +13,7 @@ double njs_value_to_number(njs_value_t *value); double njs_number_parse(const u_char **start, const u_char *end); -int64_t njs_number_radix_parse(u_char *p, u_char *end, uint8_t radix, - nxt_bool_t exact); +int64_t njs_number_radix_parse(u_char **start, u_char *end, uint8_t radix); njs_ret_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string, const njs_value_t *number); njs_ret_t njs_number_constructor(njs_vm_t *vm, njs_value_t *args, diff -r fc6c8da00858 -r be8d68d4b8b5 njs/njs_parser.c --- a/njs/njs_parser.c Thu May 25 14:16:31 2017 +0300 +++ b/njs/njs_parser.c Fri May 26 20:07:24 2017 +0300 @@ -2429,12 +2429,13 @@ njs_parser_escape_string_create(njs_vm_t goto invalid; } - u = njs_number_radix_parse(src, hex_end, 16, 1); - if (nxt_slow_path(u < 0)) { + u = njs_number_radix_parse(&src, hex_end, 16); + + if (nxt_slow_path(src != hex_end)) { goto invalid; } - src = hex_end + skip; + src += skip; size += nxt_utf8_size(u); length++; diff -r fc6c8da00858 -r be8d68d4b8b5 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu May 25 14:16:31 2017 +0300 +++ b/njs/test/njs_unit_test.c Fri May 26 20:07:24 2017 +0300 @@ -3139,6 +3139,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("'\\u'"), nxt_string("SyntaxError: Invalid Unicode code point \"\\u\" in 1") }, + { nxt_string("'\\uzzzz'"), + nxt_string("SyntaxError: Invalid Unicode code point \"\\uzzzz\" in 1") }, + { nxt_string("'\\u03B'"), nxt_string("SyntaxError: Invalid Unicode code point \"\\u03B\" in 1") }, @@ -7050,8 +7053,11 @@ static njs_unit_test_t njs_test[] = { nxt_string("parseInt('0x')"), nxt_string("NaN") }, - { nxt_string("parseInt('0x', 10)"), - nxt_string("0") }, + { nxt_string("parseInt('z')"), + nxt_string("NaN") }, + + { nxt_string("parseInt('0xz')"), + nxt_string("NaN") }, { nxt_string("parseInt('0x', 16)"), nxt_string("NaN") }, From igor at sysoev.ru Fri May 26 17:14:32 2017 From: igor at sysoev.ru (Igor Sysoev) Date: Fri, 26 May 2017 17:14:32 +0000 Subject: [njs] A small rbtree insert fixup optimization. Message-ID: details: http://hg.nginx.org/njs/rev/7156ba123eae branches: changeset: 343:7156ba123eae user: Igor Sysoev date: Fri May 26 20:10:22 2017 +0300 description: A small rbtree insert fixup optimization. Thanks to ??? (Hong Zhi Dao). diffstat: nxt/nxt_rbtree.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) diffs (36 lines): diff -r be8d68d4b8b5 -r 7156ba123eae nxt/nxt_rbtree.c --- a/nxt/nxt_rbtree.c Fri May 26 20:07:24 2017 +0300 +++ b/nxt/nxt_rbtree.c Fri May 26 20:10:22 2017 +0300 @@ -129,11 +129,15 @@ nxt_rbtree_insert_fixup(nxt_rbtree_node_ nxt_rbtree_left_rotate(node); } + /* + * nxt_rbtree_left_rotate() swaps parent and + * child whilst keeps grandparent the same. + */ parent = node->parent; + parent->color = NXT_RBTREE_BLACK; + grandparent->color = NXT_RBTREE_RED; - grandparent = parent->parent; - grandparent->color = NXT_RBTREE_RED; nxt_rbtree_right_rotate(grandparent); /* * nxt_rbtree_right_rotate() does not change node->parent @@ -153,11 +157,12 @@ nxt_rbtree_insert_fixup(nxt_rbtree_node_ nxt_rbtree_right_rotate(node); } + /* See the comment in the symmetric branch above. */ parent = node->parent; + parent->color = NXT_RBTREE_BLACK; + grandparent->color = NXT_RBTREE_RED; - grandparent = parent->parent; - grandparent->color = NXT_RBTREE_RED; nxt_rbtree_left_rotate(grandparent); /* See the comment in the symmetric branch above. */ From ru at nginx.com Fri May 26 20:02:36 2017 From: ru at nginx.com (Ruslan Ermilov) Date: Fri, 26 May 2017 20:02:36 +0000 Subject: [nginx] Introduced ngx_tcp_nodelay(). Message-ID: details: http://hg.nginx.org/nginx/rev/ed1101bbf19f branches: changeset: 7007:ed1101bbf19f user: Ruslan Ermilov date: Fri May 26 22:52:48 2017 +0300 description: Introduced ngx_tcp_nodelay(). diffstat: src/core/ngx_connection.c | 43 ++++++++++++++++ src/core/ngx_connection.h | 1 + src/http/ngx_http_request.c | 27 +--------- src/http/ngx_http_upstream.c | 96 ++++++----------------------------- src/http/v2/ngx_http_v2.c | 25 +-------- src/stream/ngx_stream_core_module.c | 19 +------ src/stream/ngx_stream_proxy_module.c | 19 +------ 7 files changed, 72 insertions(+), 158 deletions(-) diffs (366 lines): diff -r 9552758a786e -r ed1101bbf19f src/core/ngx_connection.c --- a/src/core/ngx_connection.c Thu May 25 15:57:59 2017 +0300 +++ b/src/core/ngx_connection.c Fri May 26 22:52:48 2017 +0300 @@ -1346,6 +1346,49 @@ ngx_connection_local_sockaddr(ngx_connec ngx_int_t +ngx_tcp_nodelay(ngx_connection_t *c) +{ + int tcp_nodelay; + + if (c->tcp_nodelay != NGX_TCP_NODELAY_UNSET) { + return NGX_OK; + } + + ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, "tcp_nodelay"); + + tcp_nodelay = 1; + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) + == -1) + { +#if (NGX_SOLARIS) + if (c->log_error == NGX_ERROR_INFO) { + + /* Solaris returns EINVAL if a socket has been shut down */ + c->log_error = NGX_ERROR_IGNORE_EINVAL; + + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + + c->log_error = NGX_ERROR_INFO; + + return NGX_ERROR; + } +#endif + + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + return NGX_ERROR; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; + + return NGX_OK; +} + + +ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text) { ngx_uint_t level; diff -r 9552758a786e -r ed1101bbf19f src/core/ngx_connection.h --- a/src/core/ngx_connection.h Thu May 25 15:57:59 2017 +0300 +++ b/src/core/ngx_connection.h Fri May 26 22:52:48 2017 +0300 @@ -214,6 +214,7 @@ void ngx_close_connection(ngx_connection void ngx_close_idle_connections(ngx_cycle_t *cycle); ngx_int_t ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s, ngx_uint_t port); +ngx_int_t ngx_tcp_nodelay(ngx_connection_t *c); ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text); ngx_connection_t *ngx_get_connection(ngx_socket_t s, ngx_log_t *log); diff -r 9552758a786e -r ed1101bbf19f src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Thu May 25 15:57:59 2017 +0300 +++ b/src/http/ngx_http_request.c Fri May 26 22:52:48 2017 +0300 @@ -3061,30 +3061,9 @@ ngx_http_set_keepalive(ngx_http_request_ tcp_nodelay = 1; } - if (tcp_nodelay - && clcf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) - { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) - == -1) - { -#if (NGX_SOLARIS) - /* Solaris returns EINVAL if a socket has been shut down */ - c->log_error = NGX_ERROR_IGNORE_EINVAL; -#endif - - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - - c->log_error = NGX_ERROR_INFO; - ngx_http_close_connection(c); - return; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_close_connection(c); + return; } #if 0 diff -r 9552758a786e -r ed1101bbf19f src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Thu May 25 15:57:59 2017 +0300 +++ b/src/http/ngx_http_upstream.c Fri May 26 22:52:48 2017 +0300 @@ -1606,7 +1606,6 @@ static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_connection_t *c) { - int tcp_nodelay; ngx_int_t rc; ngx_http_core_loc_conf_t *clcf; @@ -1646,22 +1645,10 @@ ngx_http_upstream_ssl_init_connection(ng clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, + if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + return; } } @@ -2014,7 +2001,6 @@ static ngx_int_t ngx_http_upstream_send_request_body(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_uint_t do_write) { - int tcp_nodelay; ngx_int_t rc; ngx_chain_t *out, *cl, *ln; ngx_connection_t *c; @@ -2051,20 +2037,8 @@ ngx_http_upstream_send_request_body(ngx_ c = u->peer.connection; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - return NGX_ERROR; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + return NGX_ERROR; } r->read_event_handler = ngx_http_upstream_read_request_handler; @@ -2822,7 +2796,6 @@ ngx_http_upstream_process_body_in_memory static void ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) { - int tcp_nodelay; ssize_t n; ngx_int_t rc; ngx_event_pipe_t *p; @@ -2903,21 +2876,9 @@ ngx_http_upstream_send_response(ngx_http return; } - if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - return; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; } n = u->buffer.last - u->buffer.pos; @@ -3176,7 +3137,6 @@ ngx_http_upstream_send_response(ngx_http static void ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u) { - int tcp_nodelay; ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; @@ -3194,37 +3154,15 @@ ngx_http_upstream_upgrade(ngx_http_reque r->write_event_handler = ngx_http_upstream_upgraded_write_downstream; if (clcf->tcp_nodelay) { - tcp_nodelay = 1; - - if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - return; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; - } - - if (u->peer.connection->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, u->peer.connection->log, 0, - "tcp_nodelay"); - - if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(u->peer.connection, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - return; - } - - u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET; + + if (ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; + } + + if (ngx_tcp_nodelay(u->peer.connection) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; } } diff -r 9552758a786e -r ed1101bbf19f src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu May 25 15:57:59 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Fri May 26 22:52:48 2017 +0300 @@ -529,29 +529,8 @@ ngx_http_v2_send_output_queue(ngx_http_v tcp_nodelay = 1; } - if (tcp_nodelay - && clcf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) - { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) - == -1) - { -#if (NGX_SOLARIS) - /* Solaris returns EINVAL if a socket has been shut down */ - c->log_error = NGX_ERROR_IGNORE_EINVAL; -#endif - - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - - c->log_error = NGX_ERROR_INFO; - goto error; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + goto error; } for ( /* void */ ; out; out = fn) { diff -r 9552758a786e -r ed1101bbf19f src/stream/ngx_stream_core_module.c --- a/src/stream/ngx_stream_core_module.c Thu May 25 15:57:59 2017 +0300 +++ b/src/stream/ngx_stream_core_module.c Fri May 26 22:52:48 2017 +0300 @@ -309,7 +309,6 @@ ngx_int_t ngx_stream_core_content_phase(ngx_stream_session_t *s, ngx_stream_phase_handler_t *ph) { - int tcp_nodelay; ngx_connection_t *c; ngx_stream_core_srv_conf_t *cscf; @@ -321,22 +320,10 @@ ngx_stream_core_content_phase(ngx_stream if (c->type == SOCK_STREAM && cscf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + && ngx_tcp_nodelay(c) != NGX_OK) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return NGX_OK; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return NGX_OK; } cscf->handler(s); diff -r 9552758a786e -r ed1101bbf19f src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Thu May 25 15:57:59 2017 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Fri May 26 22:52:48 2017 +0300 @@ -729,7 +729,6 @@ ngx_stream_proxy_connect(ngx_stream_sess static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) { - int tcp_nodelay; u_char *p; ngx_chain_t *cl; ngx_connection_t *c, *pc; @@ -745,22 +744,10 @@ ngx_stream_proxy_init_upstream(ngx_strea if (pc->type == SOCK_STREAM && cscf->tcp_nodelay - && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + && ngx_tcp_nodelay(pc) != NGX_OK) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(pc->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(pc, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_stream_proxy_next_upstream(s); - return; - } - - pc->tcp_nodelay = NGX_TCP_NODELAY_SET; + ngx_stream_proxy_next_upstream(s); + return; } pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); From sepherosa at gmail.com Sat May 27 01:07:00 2017 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Sat, 27 May 2017 09:07:00 +0800 Subject: [PATCH] Be more verbose in ngx_setaffinity() In-Reply-To: <20170526153141.GF55433@mdounin.ru> References: <20170526153141.GF55433@mdounin.ru> Message-ID: On Fri, May 26, 2017 at 11:31 PM, Maxim Dounin wrote: > Hello! > > On Fri, May 26, 2017 at 04:42:51PM +0800, Sepherosa Ziehau wrote: > >> Hi all, >> >> Patch is here: >> https://leaf.dragonflybsd.org/~sephe/verb_setaffinity.diff > > Process PID is present in error log messages, it is believed to be > enough to identify which worker uses which CPU. It is also looks > like a layering violation to print ngx_worker from a generic Thought it was just for worker's affinity setting. Since you say its a generic function, I will drop the patch then. > function which knows nothing if it is being called in a worker > process or not. > > Do you have any specific reasons for the change? I was debugging the reuseport listen socket cpu affinity. Thanks, sephe -- Tomorrow Will Never Die From sepherosa at gmail.com Sat May 27 01:13:55 2017 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Sat, 27 May 2017 09:13:55 +0800 Subject: [PATCH] worker_cpu_affinity support for DragonFlyBSD In-Reply-To: <20170526160401.GG55433@mdounin.ru> References: <20170526160401.GG55433@mdounin.ru> Message-ID: Hi Maxim, Your patch works. Thank you! Thanks, sephe On Sat, May 27, 2017 at 12:04 AM, Maxim Dounin wrote: > Hello! > > On Fri, May 26, 2017 at 02:56:06PM +0800, Sepherosa Ziehau wrote: > >> Hi all, >> >> The patch is here: >> https://leaf.dragonflybsd.org/~sephe/nginx_dfly_affinity.diff >> >> Unlike FreeBSD, we adopted sched_setaffinity() syscall for process CPU affinity. > > A better solution might be to move sched_setaffinity() test from > auto/os/linux to auto/unix instead. Patch below (untested). > > # HG changeset patch > # User Maxim Dounin > # Date 1495814031 -10800 > # Fri May 26 18:53:51 2017 +0300 > # Node ID d4d316c4503f7b9bbf47b0006822e4438e6e641a > # Parent 9552758a786e20c70130427298895bc782a754c5 > Configure: sched_setaffinity() test moved to auto/unix. > > The sched_setaffinity() function was introduced in DragonFly BSD 4.7, > so it is no longer Linux-specific. > > diff --git a/auto/os/linux b/auto/os/linux > --- a/auto/os/linux > +++ b/auto/os/linux > @@ -157,20 +157,6 @@ ngx_feature_test="if (prctl(PR_SET_DUMPA > . auto/feature > > > -# sched_setaffinity() > - > -ngx_feature="sched_setaffinity()" > -ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" > -ngx_feature_run=no > -ngx_feature_incs="#include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="cpu_set_t mask; > - CPU_ZERO(&mask); > - sched_setaffinity(0, sizeof(cpu_set_t), &mask)" > -. auto/feature > - > - > # crypt_r() > > ngx_feature="crypt_r()" > diff --git a/auto/unix b/auto/unix > --- a/auto/unix > +++ b/auto/unix > @@ -300,6 +300,18 @@ if [ $ngx_found = no ]; then > fi > > > +ngx_feature="sched_setaffinity()" > +ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" > +ngx_feature_run=no > +ngx_feature_incs="#include " > +ngx_feature_path= > +ngx_feature_libs= > +ngx_feature_test="cpu_set_t mask; > + CPU_ZERO(&mask); > + sched_setaffinity(0, sizeof(cpu_set_t), &mask)" > +. auto/feature > + > + > ngx_feature="SO_SETFIB" > ngx_feature_name="NGX_HAVE_SETFIB" > ngx_feature_run=no > > -- > Maxim Dounin > http://nginx.org/ > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- Tomorrow Will Never Die From igor at sysoev.ru Mon May 29 05:08:26 2017 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 29 May 2017 05:08:26 +0000 Subject: [njs] Unicode code point parsing optimization. Message-ID: details: http://hg.nginx.org/njs/rev/7f1f3dcb278f branches: changeset: 344:7f1f3dcb278f user: Igor Sysoev date: Sat May 27 18:02:09 2017 +0300 description: Unicode code point parsing optimization. diffstat: njs/njs_parser.c | 45 ++++++++++++++++++++++++--------------------- 1 files changed, 24 insertions(+), 21 deletions(-) diffs (93 lines): diff -r 7156ba123eae -r 7f1f3dcb278f njs/njs_parser.c --- a/njs/njs_parser.c Fri May 26 20:10:22 2017 +0300 +++ b/njs/njs_parser.c Sat May 27 18:02:09 2017 +0300 @@ -2303,7 +2303,7 @@ njs_parser_escape_string_create(njs_vm_t njs_value_t *value) { u_char c, *p, *start, *dst, *src, *end, *hex_end; - size_t size, length, hex_length, skip; + size_t size, length, hex_length; int64_t u; start = NULL; @@ -2334,35 +2334,25 @@ njs_parser_escape_string_create(njs_vm_t switch (c) { case 'u': - skip = 0; hex_length = 4; - /* * A character after "u" can be safely tested here * because there is always a closing quote at the * end of string: ...\u". */ - if (*src == '{') { - hex_length = 0; - src++; - - for (p = src; p < end && *p != '}'; p++) { - hex_length++; - } - - if (hex_length == 0 || hex_length > 6) { - goto invalid; - } - - skip = 1; + if (*src != '{') { + goto hex_length_test; } + src++; + hex_length = 0; + hex_end = end; + goto hex; case 'x': - skip = 0; hex_length = 2; - goto hex; + goto hex_length_test; case '0': c = '\0'; @@ -2421,7 +2411,7 @@ njs_parser_escape_string_create(njs_vm_t continue; - hex: + hex_length_test: hex_end = src + hex_length; @@ -2429,13 +2419,26 @@ njs_parser_escape_string_create(njs_vm_t goto invalid; } + hex: + + p = src; u = njs_number_radix_parse(&src, hex_end, 16); - if (nxt_slow_path(src != hex_end)) { + if (nxt_slow_path(u < 0)) { goto invalid; } - src += skip; + if (hex_length != 0) { + if (src != hex_end) { + goto invalid; + } + + } else { + if ((src - p) > 6 || src == end || *(++src) == '}') { + goto invalid; + } + } + size += nxt_utf8_size(u); length++; From igor at sysoev.ru Mon May 29 07:22:12 2017 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 29 May 2017 07:22:12 +0000 Subject: [njs] A small rbtree delete fixup optimization. Message-ID: details: http://hg.nginx.org/njs/rev/c0bdd23e740e branches: changeset: 345:c0bdd23e740e user: Igor Sysoev date: Mon May 29 10:17:36 2017 +0300 description: A small rbtree delete fixup optimization. Setting node color to black is not required here because it is already black. Besides in the original algorithm the node pointer is discarded and the node is set to tree root just to quit the loop. Thanks to ??? (Hong Zhi Dao). diffstat: nxt/nxt_rbtree.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 7f1f3dcb278f -r c0bdd23e740e nxt/nxt_rbtree.c --- a/nxt/nxt_rbtree.c Sat May 27 18:02:09 2017 +0300 +++ b/nxt/nxt_rbtree.c Mon May 29 10:17:36 2017 +0300 @@ -402,7 +402,7 @@ nxt_rbtree_delete_fixup(nxt_rbtree_t *tr nxt_rbtree_left_rotate(parent); - break; + return; } else { sibling = parent->left; @@ -440,7 +440,7 @@ nxt_rbtree_delete_fixup(nxt_rbtree_t *tr nxt_rbtree_right_rotate(parent); - break; + return; } } From mdounin at mdounin.ru Mon May 29 13:43:55 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 29 May 2017 13:43:55 +0000 Subject: [nginx] SSL: set TCP_NODELAY on SSL connections before handshake. Message-ID: details: http://hg.nginx.org/nginx/rev/29c6d66b83ba branches: changeset: 7008:29c6d66b83ba user: Maxim Dounin date: Mon May 29 16:34:29 2017 +0300 description: SSL: set TCP_NODELAY on SSL connections before handshake. With OpenSSL 1.1.0+, the workaround for handshake buffer size as introduced in a720f0b0e083 (ticket #413) no longer works, as OpenSSL no longer exposes handshake buffers, see https://github.com/openssl/openssl/commit/2e7dc7cd688. Moreover, it is no longer possible to adjust handshake buffers at all now. To avoid additional RTT if handshake uses more than 4k we now set TCP_NODELAY on SSL connections before handshake. While this still results in sub-optimal network utilization due to incomplete packets being sent, it seems to be better than nothing. diffstat: src/http/ngx_http_request.c | 25 +++++++++++++++++-------- src/stream/ngx_stream_ssl_module.c | 13 ++++++++++--- 2 files changed, 27 insertions(+), 11 deletions(-) diffs (68 lines): diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -623,14 +623,15 @@ ngx_http_create_request(ngx_connection_t static void ngx_http_ssl_handshake(ngx_event_t *rev) { - u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; - size_t size; - ssize_t n; - ngx_err_t err; - ngx_int_t rc; - ngx_connection_t *c; - ngx_http_connection_t *hc; - ngx_http_ssl_srv_conf_t *sscf; + u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; + size_t size; + ssize_t n; + ngx_err_t err; + ngx_int_t rc; + ngx_connection_t *c; + ngx_http_connection_t *hc; + ngx_http_ssl_srv_conf_t *sscf; + ngx_http_core_loc_conf_t *clcf; c = rev->data; hc = c->data; @@ -712,6 +713,14 @@ ngx_http_ssl_handshake(ngx_event_t *rev) ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "https ssl handshake: 0x%02Xd", buf[0]); + clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, + ngx_http_core_module); + + if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_close_connection(c); + return; + } + sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -352,12 +352,19 @@ ngx_stream_ssl_handler(ngx_stream_sessio static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) { - ngx_int_t rc; - ngx_stream_session_t *s; - ngx_stream_ssl_conf_t *sslcf; + ngx_int_t rc; + ngx_stream_session_t *s; + ngx_stream_ssl_conf_t *sslcf; + ngx_stream_core_srv_conf_t *cscf; s = c->data; + cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); + + if (cscf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + return NGX_ERROR; + } + if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { return NGX_ERROR; } From mdounin at mdounin.ru Mon May 29 13:43:58 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 29 May 2017 13:43:58 +0000 Subject: [nginx] Style: changed checks of ngx_ssl_create_connection() to != NGX_OK. Message-ID: details: http://hg.nginx.org/nginx/rev/03444167a3bb branches: changeset: 7009:03444167a3bb user: Maxim Dounin date: Mon May 29 16:34:35 2017 +0300 description: Style: changed checks of ngx_ssl_create_connection() to != NGX_OK. In http these checks were changed in a6d6d762c554, though mail module was missed at that time. Since then, the stream module was introduced based on mail, using "== NGX_ERROR" check. diffstat: src/mail/ngx_mail_handler.c | 2 +- src/stream/ngx_stream_ssl_module.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -222,7 +222,7 @@ ngx_mail_ssl_init_connection(ngx_ssl_t * ngx_mail_session_t *s; ngx_mail_core_srv_conf_t *cscf; - if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { + if (ngx_ssl_create_connection(ssl, c, 0) != NGX_OK) { ngx_mail_close_connection(c); return; } diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -365,7 +365,7 @@ ngx_stream_ssl_init_connection(ngx_ssl_t return NGX_ERROR; } - if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { + if (ngx_ssl_create_connection(ssl, c, 0) != NGX_OK) { return NGX_ERROR; } From mdounin at mdounin.ru Mon May 29 14:04:17 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 29 May 2017 14:04:17 +0000 Subject: [nginx] Configure: sched_setaffinity() test moved to auto/unix. Message-ID: details: http://hg.nginx.org/nginx/rev/c1524829af3d branches: changeset: 7010:c1524829af3d user: Maxim Dounin date: Mon May 29 16:48:30 2017 +0300 description: Configure: sched_setaffinity() test moved to auto/unix. The sched_setaffinity() function was introduced in DragonFly BSD 4.7, so it is no longer Linux-specific. Prodded by Sepherosa Ziehau. diffstat: auto/os/linux | 14 -------------- auto/unix | 12 ++++++++++++ 2 files changed, 12 insertions(+), 14 deletions(-) diffs (46 lines): diff --git a/auto/os/linux b/auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -157,20 +157,6 @@ ngx_feature_test="if (prctl(PR_SET_DUMPA . auto/feature -# sched_setaffinity() - -ngx_feature="sched_setaffinity()" -ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="cpu_set_t mask; - CPU_ZERO(&mask); - sched_setaffinity(0, sizeof(cpu_set_t), &mask)" -. auto/feature - - # crypt_r() ngx_feature="crypt_r()" diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -300,6 +300,18 @@ if [ $ngx_found = no ]; then fi +ngx_feature="sched_setaffinity()" +ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" +ngx_feature_run=no +ngx_feature_incs="#include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="cpu_set_t mask; + CPU_ZERO(&mask); + sched_setaffinity(0, sizeof(cpu_set_t), &mask)" +. auto/feature + + ngx_feature="SO_SETFIB" ngx_feature_name="NGX_HAVE_SETFIB" ngx_feature_run=no From mdounin at mdounin.ru Mon May 29 14:04:54 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 29 May 2017 17:04:54 +0300 Subject: [PATCH] worker_cpu_affinity support for DragonFlyBSD In-Reply-To: References: <20170526160401.GG55433@mdounin.ru> Message-ID: <20170529140454.GS55433@mdounin.ru> Hello! On Sat, May 27, 2017 at 09:13:55AM +0800, Sepherosa Ziehau wrote: > Hi Maxim, > > Your patch works. Thank you! Committed, thanks for testing. [...] -- Maxim Dounin http://nginx.org/ From igor at sysoev.ru Mon May 29 19:13:53 2017 From: igor at sysoev.ru (Igor Sysoev) Date: Mon, 29 May 2017 19:13:53 +0000 Subject: [njs] A fix of bug introduced in changeset 7f1f3dcb278f. Message-ID: details: http://hg.nginx.org/njs/rev/4e2da602c2a3 branches: changeset: 346:4e2da602c2a3 user: Igor Sysoev date: Mon May 29 22:13:21 2017 +0300 description: A fix of bug introduced in changeset 7f1f3dcb278f. diffstat: njs/njs_parser.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r c0bdd23e740e -r 4e2da602c2a3 njs/njs_parser.c --- a/njs/njs_parser.c Mon May 29 10:17:36 2017 +0300 +++ b/njs/njs_parser.c Mon May 29 22:13:21 2017 +0300 @@ -2434,7 +2434,7 @@ njs_parser_escape_string_create(njs_vm_t } } else { - if ((src - p) > 6 || src == end || *(++src) == '}') { + if ((src - p) > 6 || src == end || *src++ != '}') { goto invalid; } } From arut at nginx.com Mon May 29 20:40:11 2017 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 29 May 2017 20:40:11 +0000 Subject: [nginx] Fixed background requests with asynchronous operations. Message-ID: details: http://hg.nginx.org/nginx/rev/5e05118678af branches: changeset: 7011:5e05118678af user: Roman Arutyunyan date: Mon May 29 23:33:38 2017 +0300 description: Fixed background requests with asynchronous operations. If the main request was finalized while a background request performed an asynchronous operation, the main request ended up in ngx_http_writer() and was not finalized until a network event or a timeout. For example, cache background update with aio enabled made nginx unable to process further client requests or close the connection, keeping it open until client closes it. Now regular finalization of the main request is not suspended because of an asynchronous operation in another request. If a background request was terminated while an asynchronous operation was in progress, background request's write event handler was changed to ngx_http_request_finalizer() and never called again. Now, whenever a request is terminated while an asynchronous operation is in progress, connection error flag is set to make further finalizations of any request with this connection lead to termination. These issues appeared in 1aeaae6e9446 (not yet released). diffstat: src/http/ngx_http_request.c | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diffs (32 lines): diff -r c1524829af3d -r 5e05118678af src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Mon May 29 16:48:30 2017 +0300 +++ b/src/http/ngx_http_request.c Mon May 29 23:33:38 2017 +0300 @@ -2331,10 +2331,6 @@ ngx_http_finalize_request(ngx_http_reque return; } - if (r->main->blocked) { - r->write_event_handler = ngx_http_request_finalizer; - } - ngx_http_terminate_request(r, rc); return; } @@ -2449,7 +2445,7 @@ ngx_http_finalize_request(ngx_http_reque return; } - if (r->buffered || c->buffered || r->postponed || r->blocked) { + if (r->buffered || c->buffered || r->postponed) { if (ngx_http_set_write_handler(r) != NGX_OK) { ngx_http_terminate_request(r, 0); @@ -2530,6 +2526,8 @@ ngx_http_terminate_request(ngx_http_requ if (mr->write_event_handler) { if (mr->blocked) { + r->connection->error = 1; + r->write_event_handler = ngx_http_request_finalizer; return; } From piotrsikora at google.com Tue May 30 03:26:50 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 29 May 2017 20:26:50 -0700 Subject: [PATCH] HTTP/2: add debug logging of pseudo-headers and cookies In-Reply-To: <3433727.YHEi7QJnSm@vbart-workstation> References: <2626325.vZ0dWXWuNK@vbart-workstation> <164b95f24f414359c5b8.1493074726@piotrsikora.sfo.corp.google.com> <3433727.YHEi7QJnSm@vbart-workstation> Message-ID: Hey Valentin, > + h = ngx_list_push(&r->headers_in.headers); > + if (h == NULL) { > + return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); This needs to wrap, since the line is too long. Otherwise, looks good, thanks! Best regards, Piotr Sikora From Saju.Pillai at concur.com Tue May 30 05:15:52 2017 From: Saju.Pillai at concur.com (Pillai, Saju) Date: Tue, 30 May 2017 05:15:52 +0000 Subject: Accessing parsed locations in post-configuration Message-ID: Hello, I would like to inspect the parsed locations (ngx_http_core_loc_conf_s->static_locations & ->regex_locations) in my module post-configuration callback. However using loc_conf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); I always get loc_conf->static_locations & loc_conf->regex_locations as NULL. Any pointers are appreciated. -srp ________________________________ This e-mail message is authorized for use by the intended recipient only and may contain information that is privileged and confidential. If you received this message in error, please call us immediately at (425) 590-5000 and ask to speak to the message sender. Please do not copy, disseminate, or retain this message unless you are the intended recipient. In addition, to ensure the security of your data, please do not send any unencrypted credit card or personally identifiable information to this email address. Thank you. From borodin at octonica.com Tue May 30 10:28:03 2017 From: borodin at octonica.com (Andrew Borodin) Date: Tue, 30 May 2017 15:28:03 +0500 Subject: Use primes for hashtable size Message-ID: Hi, nginxers! We often use hashtable sizes equal to the power of 2. This can be damaging for a hashtable. I haven't found any mitigation for this in nginx code. So I made my own. If this issue is addressed somewhere just ignore my message. Or I'd be happy if someone will point me it. For the explanation of problem see https://stackoverflow.com/questions/3980117/hash-table-why-size-should-be-prime Code is checked for correctness of ngx_hash_min_prime(), I haven't done any regression testing, sorry. Also beware that I've changed state of paremeter hinit. I'm not sure this is acceptable. Thank you for your attention. Best regards, Andrey Borodin, Octonica. -------------- next part -------------- A non-text attachment was scrubbed... Name: primes_for_hash.patch Type: application/octet-stream Size: 5777 bytes Desc: not available URL: From mdounin at mdounin.ru Tue May 30 13:01:37 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 30 May 2017 16:01:37 +0300 Subject: Use primes for hashtable size In-Reply-To: References: Message-ID: <20170530130137.GT55433@mdounin.ru> Hello! On Tue, May 30, 2017 at 03:28:03PM +0500, Andrew Borodin wrote: > Hi, nginxers! > > We often use hashtable sizes equal to the power of 2. This can be > damaging for a hashtable. I haven't found any mitigation for this in > nginx code. So I made my own. If this issue is addressed somewhere > just ignore my message. Or I'd be happy if someone will point me it. > > For the explanation of problem see > https://stackoverflow.com/questions/3980117/hash-table-why-size-should-be-prime > > Code is checked for correctness of ngx_hash_min_prime(), I haven't > done any regression testing, sorry. The maximum size of hash table as specified by the hinit->max_size field is indeed maximum size, and not the size of the hash table. Following code in the ngx_hash_init() will try hard to find to find out an optimal hash size for a given set of values within the maximum size specified, and will test all the prime numbers as well. I see no reasons to additionally limit the maximum size to a prime number. If you think there are some, please be more specific. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue May 30 14:36:23 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 30 May 2017 14:36:23 +0000 Subject: [nginx] Updated OpenSSL used for win32 builds. Message-ID: details: http://hg.nginx.org/nginx/rev/9b26edd391ab branches: changeset: 7012:9b26edd391ab user: Maxim Dounin date: Tue May 30 17:14:00 2017 +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 @@ -6,7 +6,7 @@ TEMP = tmp CC = cl OBJS = objs.msvc8 -OPENSSL = openssl-1.0.2k +OPENSSL = openssl-1.0.2l ZLIB = zlib-1.2.11 PCRE = pcre-8.40 From mdounin at mdounin.ru Tue May 30 14:57:37 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 30 May 2017 14:57:37 +0000 Subject: [nginx] nginx-1.13.1-RELEASE Message-ID: details: http://hg.nginx.org/nginx/rev/539f7893ecb9 branches: changeset: 7013:539f7893ecb9 user: Maxim Dounin date: Tue May 30 17:55:22 2017 +0300 description: nginx-1.13.1-RELEASE diffstat: docs/xml/nginx/changes.xml | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 98 insertions(+), 0 deletions(-) diffs (108 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,104 @@ + + + + +?????? ? ???????? ????????? ????????? set_real_ip_from +????? ????????? ??? ?????. + + +now a hostname can be used +as the "set_real_ip_from" directive parameter. + + + + + +????????? ? ???????? ????????? ?????????? ??? vim. + + +vim syntax highlighting scripts improvements. + + + + + +????????? worker_cpu_affinity ?????? ???????? ?? DragonFly BSD.
+??????? Sepherosa Ziehau. +
+ +the "worker_cpu_affinity" directive now works on DragonFly BSD.
+Thanks to Sepherosa Ziehau. +
+
+ + + +SSL renegotiation ? ??????????? ? ???????? +?? ??????? ??? ????????????? OpenSSL ?? 1.1.0. + + +SSL renegotiation on backend connections +did not work when using OpenSSL before 1.1.0. + + + + + +nginx ?? ????????? ? Oracle Developer Studio 12.5. + + +nginx could not be built with Oracle Developer Studio 12.5. + + + + + +?????? cache manager ?????????? ??????????????? ?????? +??? ??????? ???? ?? max_size. + + +now cache manager ignores long locked cache entries +when cleaning cache based on the "max_size" parameter. + + + + + +?????????? SSL-?????????? ????? ???????????, ???? ????????????? +?????????? accept ? ???????? proxy_protocol ????????? listen. + + +client SSL connections were immediately closed if deferred accept +and the "proxy_protocol" parameter of the "listen" directive were used. + + + + + +? ????????? proxy_cache_background_update. + + +in the "proxy_cache_background_update" directive. + + + + + +?????? ????????? tcp_nodelay +????????????? ????? TCP_NODELAY ????? SSL handshake. + + +now the "tcp_nodelay" directive +sets the TCP_NODELAY option before an SSL handshake. + + + +
+ + From mdounin at mdounin.ru Tue May 30 14:57:39 2017 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 30 May 2017 14:57:39 +0000 Subject: [nginx] release-1.13.1 tag Message-ID: details: http://hg.nginx.org/nginx/rev/b4cb75066262 branches: changeset: 7014:b4cb75066262 user: Maxim Dounin date: Tue May 30 17:55:23 2017 +0300 description: release-1.13.1 tag diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -413,3 +413,4 @@ d8b321a876d6254e9e98795e3b194ef053290354 7f394e433f0003222aa6531931ecc0b24740d5e4 release-1.11.12 3d0e8655f897959e48cc74e87670bb5492a58871 release-1.11.13 3671096a45bce570a2afa20b9faf42c7fb0f7e66 release-1.13.0 +539f7893ecb96bee60965528c8958d7eb2f1ce6b release-1.13.1 From vbart at nginx.com Tue May 30 16:30:50 2017 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 30 May 2017 16:30:50 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/dfed742c0183 branches: changeset: 7015:dfed742c0183 user: Valentin Bartenev date: Tue May 30 19:29:45 2017 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r b4cb75066262 -r dfed742c0183 src/core/nginx.h --- a/src/core/nginx.h Tue May 30 17:55:23 2017 +0300 +++ b/src/core/nginx.h Tue May 30 19:29:45 2017 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1013001 -#define NGINX_VERSION "1.13.1" +#define nginx_version 1013002 +#define NGINX_VERSION "1.13.2" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From vbart at nginx.com Tue May 30 16:30:58 2017 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 30 May 2017 16:30:58 +0000 Subject: [nginx] HTTP/2: add debug logging of pseudo-headers and cookies. Message-ID: details: http://hg.nginx.org/nginx/rev/ab6ef3037840 branches: changeset: 7016:ab6ef3037840 user: Piotr Sikora date: Tue May 30 17:42:27 2017 +0300 description: HTTP/2: add debug logging of pseudo-headers and cookies. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2.c | 62 ++++++++++++++++++++++++++-------------------- 1 files changed, 35 insertions(+), 27 deletions(-) diffs (82 lines): diff -r dfed742c0183 -r ab6ef3037840 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Tue May 30 19:29:45 2017 +0300 +++ b/src/http/v2/ngx_http_v2.c Tue May 30 17:42:27 2017 +0300 @@ -1568,6 +1568,10 @@ ngx_http_v2_state_process_header(ngx_htt rc = ngx_http_v2_pseudo_header(r, header); if (rc == NGX_OK) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http2 pseudo-header: \":%V: %V\"", + &header->name, &header->value); + return ngx_http_v2_state_header_complete(h2c, pos, end); } @@ -1609,36 +1613,40 @@ ngx_http_v2_state_process_header(ngx_htt NGX_HTTP_V2_INTERNAL_ERROR); } - return ngx_http_v2_state_header_complete(h2c, pos, end); - } - - h = ngx_list_push(&r->headers_in.headers); - if (h == NULL) { - return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); - } - - h->key.len = header->name.len; - h->key.data = header->name.data; - - /* TODO Optimization: precalculate hash and handler for indexed headers. */ - h->hash = ngx_hash_key(h->key.data, h->key.len); - - h->value.len = header->value.len; - h->value.data = header->value.data; - - h->lowcase_key = h->key.data; - - cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - - hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, - h->lowcase_key, h->key.len); - - if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - goto error; + } else { + h = ngx_list_push(&r->headers_in.headers); + if (h == NULL) { + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + + h->key.len = header->name.len; + h->key.data = header->name.data; + + /* + * TODO Optimization: precalculate hash + * and handler for indexed headers. + */ + h->hash = ngx_hash_key(h->key.data, h->key.len); + + h->value.len = header->value.len; + h->value.data = header->value.data; + + h->lowcase_key = h->key.data; + + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + + hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, + h->lowcase_key, h->key.len); + + if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { + goto error; + } } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http2 http header: \"%V: %V\"", &h->key, &h->value); + "http2 http header: \"%V: %V\"", + &header->name, &header->value); return ngx_http_v2_state_header_complete(h2c, pos, end); From vbart at nginx.com Tue May 30 16:38:18 2017 From: vbart at nginx.com (Valentin V. Bartenev) Date: Tue, 30 May 2017 19:38:18 +0300 Subject: [PATCH] HTTP/2: add debug logging of pseudo-headers and cookies In-Reply-To: References: <2626325.vZ0dWXWuNK@vbart-workstation> <3433727.YHEi7QJnSm@vbart-workstation> Message-ID: <3284410.RuuiyJfPg4@vbart-workstation> On Monday 29 May 2017 20:26:50 Piotr Sikora via nginx-devel wrote: > Hey Valentin, > > > + h = ngx_list_push(&r->headers_in.headers); > > + if (h == NULL) { > > + return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); > > This needs to wrap, since the line is too long. > > Otherwise, looks good, thanks! > Committed: http://hg.nginx.org/nginx/rev/ab6ef3037840 Thank you! wbr, Valentin V. Bartenev From xeioex at nginx.com Tue May 30 18:02:33 2017 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Tue, 30 May 2017 18:02:33 +0000 Subject: [njs] Added support of hex literals. Message-ID: details: http://hg.nginx.org/njs/rev/a38c33e9f728 branches: changeset: 347:a38c33e9f728 user: Dmitry Volyntsev date: Tue May 30 19:35:08 2017 +0300 description: Added support of hex literals. diffstat: njs/njs_lexer.c | 57 ++++---------------- njs/njs_number.c | 87 ++++++++++++++++++++++---------- njs/njs_number.h | 5 +- njs/njs_parser.c | 18 +++--- njs/njs_string.c | 64 ++++++++++++++++++++--- njs/njs_string.h | 3 +- njs/njs_vm.c | 31 +++------- njs/test/njs_unit_test.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 275 insertions(+), 114 deletions(-) diffs (682 lines): diff -r 4e2da602c2a3 -r a38c33e9f728 njs/njs_lexer.c --- a/njs/njs_lexer.c Mon May 29 22:13:21 2017 +0300 +++ b/njs/njs_lexer.c Tue May 30 19:35:08 2017 +0300 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -538,59 +539,27 @@ static njs_token_t njs_lexer_number(njs_lexer_t *lexer) { u_char c, *p; - double num, frac, scale; - - /* TODO: "1e2" */ p = lexer->start; c = p[-1]; - /* Values below '0' become >= 208. */ - c = c - '0'; - - num = c; - - if (c != 0) { - - while (p < lexer->end) { - c = *p; + /* Hexadecimal literal values. */ - /* Values below '0' become >= 208. */ - c = c - '0'; + if (c == '0' && p != lexer->end && (*p == 'x' || *p == 'X')) { + p++; - if (nxt_slow_path(c > 9)) { - break; - } + if (p == lexer->end) { + return NJS_TOKEN_ILLEGAL; + } - num = num * 10 + c; - p++; - } + lexer->start = p; + lexer->number = njs_number_hex_parse(&lexer->start, lexer->end); + + return NJS_TOKEN_NUMBER; } - if (*p == '.') { - - frac = 0; - scale = 1; - - for (p++; p < lexer->end; p++) { - c = *p; - - /* Values below '0' become >= 208. */ - c = c - '0'; - - if (nxt_slow_path(c > 9)) { - break; - } - - frac = frac * 10 + c; - scale *= 10; - } - - num += frac / scale; - } - - lexer->number = num; - lexer->start = p; + lexer->start = p - 1; + lexer->number = njs_number_dec_parse(&lexer->start, lexer->end); return NJS_TOKEN_NUMBER; } diff -r 4e2da602c2a3 -r a38c33e9f728 njs/njs_number.c --- a/njs/njs_number.c Mon May 29 22:13:21 2017 +0300 +++ b/njs/njs_number.c Tue May 30 19:35:08 2017 +0300 @@ -37,20 +37,21 @@ static njs_ret_t njs_number_to_string_ra double number, uint32_t radix); -double -njs_value_to_number(njs_value_t *value) +uint32_t +njs_value_to_index(njs_value_t *value) { + double num; njs_array_t *array; + num = NAN; + if (nxt_fast_path(njs_is_numeric(value))) { - return value->data.u.number; - } + num = value->data.u.number; - if (njs_is_string(value)) { - return njs_string_to_number(value, 1); - } + } else if (njs_is_string(value)) { + num = njs_string_to_index(value); - if (njs_is_array(value)) { + } else if (njs_is_array(value)) { array = value->data.u.array; @@ -58,42 +59,39 @@ njs_value_to_number(njs_value_t *value) if (array->length == 0) { /* An empty array value is zero. */ - return 0.0; + return 0; } if (array->length == 1 && njs_is_valid(&array->start[0])) { /* A single value array is the zeroth array value. */ - return njs_value_to_number(&array->start[0]); + return njs_value_to_index(&array->start[0]); } } } - return NAN; + if ((uint32_t) num == num) { + return (uint32_t) num; + } + + return NJS_ARRAY_INVALID_INDEX; } double -njs_number_parse(const u_char **start, const u_char *end) +njs_number_dec_parse(u_char **start, u_char *end) { - u_char c; - double num, frac, scale; - const u_char *p; + u_char c, *p; + double num, frac, scale; /* TODO: "1e2" */ p = *start; - c = *p++; - /* Values below '0' become >= 208. */ - c = c - '0'; - - num = c; + num = 0; while (p < end) { - c = *p; - /* Values below '0' become >= 208. */ - c = c - '0'; + c = *p - '0'; if (nxt_slow_path(c > 9)) { break; @@ -109,10 +107,8 @@ njs_number_parse(const u_char **start, c scale = 1; for (p++; p < end; p++) { - c = *p; - /* Values below '0' become >= 208. */ - c = c - '0'; + c = *p - '0'; if (nxt_slow_path(c > 9)) { break; @@ -131,6 +127,43 @@ njs_number_parse(const u_char **start, c } +uint64_t +njs_number_hex_parse(u_char **start, u_char *end) +{ + u_char c, *p; + uint64_t num; + + p = *start; + + num = 0; + + while (p < end) { + c = (u_char) (*p | 0x20); + + /* Values below '0' become >= 208. */ + c = c - '0'; + + if (c > 9) { + /* Values below 'a' become >= 159. */ + c = c - ('a' - '0'); + + if (nxt_slow_path(c > 5)) { + break; + } + + c += 10; + } + + num = num * 16 + c; + p++; + } + + *start = p; + + return num; +} + + int64_t njs_number_radix_parse(u_char **start, u_char *end, uint8_t radix) { @@ -745,7 +778,7 @@ njs_number_parse_float(njs_vm_t *vm, njs num = NAN; if (nargs > 1) { - num = njs_string_to_number(&args[1], 0); + num = njs_string_to_number(&args[1], 1); } njs_number_set(&vm->retval, num); diff -r 4e2da602c2a3 -r a38c33e9f728 njs/njs_number.h --- a/njs/njs_number.h Mon May 29 22:13:21 2017 +0300 +++ b/njs/njs_number.h Tue May 30 19:35:08 2017 +0300 @@ -11,8 +11,9 @@ #include -double njs_value_to_number(njs_value_t *value); -double njs_number_parse(const u_char **start, const u_char *end); +uint32_t njs_value_to_index(njs_value_t *value); +double njs_number_dec_parse(u_char **start, u_char *end); +uint64_t njs_number_hex_parse(u_char **start, u_char *end); int64_t njs_number_radix_parse(u_char **start, u_char *end, uint8_t radix); njs_ret_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string, const njs_value_t *number); diff -r 4e2da602c2a3 -r a38c33e9f728 njs/njs_parser.c --- a/njs/njs_parser.c Mon May 29 22:13:21 2017 +0300 +++ b/njs/njs_parser.c Tue May 30 19:35:08 2017 +0300 @@ -2302,9 +2302,9 @@ static njs_token_t njs_parser_escape_string_create(njs_vm_t *vm, njs_parser_t *parser, njs_value_t *value) { - u_char c, *p, *start, *dst, *src, *end, *hex_end; - size_t size, length, hex_length; - int64_t u; + u_char c, *p, *start, *dst, *src, *end, *hex_end; + size_t size, length, hex_length; + uint64_t u; start = NULL; dst = NULL; @@ -2422,11 +2422,7 @@ njs_parser_escape_string_create(njs_vm_t hex: p = src; - u = njs_number_radix_parse(&src, hex_end, 16); - - if (nxt_slow_path(u < 0)) { - goto invalid; - } + u = njs_number_hex_parse(&src, hex_end); if (hex_length != 0) { if (src != hex_end) { @@ -2434,7 +2430,11 @@ njs_parser_escape_string_create(njs_vm_t } } else { - if ((src - p) > 6 || src == end || *src++ != '}') { + if (src == p || (src - p) > 6) { + goto invalid; + } + + if (src == end || *src++ != '}') { goto invalid; } } diff -r 4e2da602c2a3 -r a38c33e9f728 njs/njs_string.c --- a/njs/njs_string.c Mon May 29 22:13:21 2017 +0300 +++ b/njs/njs_string.c Tue May 30 19:35:08 2017 +0300 @@ -2943,12 +2943,12 @@ njs_primitive_value_to_string(njs_vm_t * double -njs_string_to_number(njs_value_t *value, nxt_bool_t exact) +njs_string_to_number(njs_value_t *value, nxt_bool_t parse_float) { + u_char *p, *start, *end; double num; size_t size; nxt_bool_t minus; - const u_char *p, *end; const size_t infinity = sizeof("Infinity") - 1; @@ -2990,19 +2990,27 @@ njs_string_to_number(njs_value_t *value, return NAN; } - if (*p >= '0' && *p <= '9') { - num = njs_number_parse(&p, end); + if (!parse_float + && p + 2 < end && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + num = njs_number_hex_parse(&p, end); } else { - if (p + infinity > end || memcmp(p, "Infinity", infinity) != 0) { - return NAN; + start = p; + num = njs_number_dec_parse(&p, end); + + if (p == start) { + if (p + infinity > end || memcmp(p, "Infinity", infinity) != 0) { + return NAN; + } + + num = INFINITY; + p += infinity; } - - num = INFINITY; - p += infinity; } - if (exact) { + if (!parse_float) { while (p < end) { if (*p != ' ' && *p != '\t') { return NAN; @@ -3016,6 +3024,42 @@ njs_string_to_number(njs_value_t *value, } +double +njs_string_to_index(njs_value_t *value) +{ + u_char *p, *end; + double num; + size_t size; + + size = value->short_string.size; + + if (size != NJS_STRING_LONG) { + p = value->short_string.start; + + } else { + size = value->data.string_size; + p = value->data.u.string->start; + } + + if (size == 0) { + return NAN; + } + + if (*p == '0' && size > 1) { + return NAN; + } + + end = p + size; + num = njs_number_dec_parse(&p, end); + + if (p != end) { + return NAN; + } + + return num; +} + + static const njs_object_prop_t njs_string_prototype_properties[] = { { diff -r 4e2da602c2a3 -r a38c33e9f728 njs/njs_string.h --- a/njs/njs_string.h Mon May 29 22:13:21 2017 +0300 +++ b/njs/njs_string.h Tue May 30 19:35:08 2017 +0300 @@ -142,7 +142,8 @@ nxt_noinline uint32_t njs_string_index(n void njs_string_offset_map_init(const u_char *start, size_t size); njs_ret_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, const njs_value_t *src); -double njs_string_to_number(njs_value_t *value, nxt_bool_t exact); +double njs_string_to_index(njs_value_t *value); +double njs_string_to_number(njs_value_t *value, nxt_bool_t parse_float); njs_ret_t njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_string_encode_uri_component(njs_vm_t *vm, njs_value_t *args, diff -r 4e2da602c2a3 -r a38c33e9f728 njs/njs_vm.c --- a/njs/njs_vm.c Mon May 29 22:13:21 2017 +0300 +++ b/njs/njs_vm.c Tue May 30 19:35:08 2017 +0300 @@ -509,7 +509,6 @@ njs_ret_t njs_vmcode_property_get(njs_vm_t *vm, njs_value_t *object, njs_value_t *property) { - double num; int32_t index; uintptr_t data; njs_ret_t ret; @@ -576,10 +575,9 @@ njs_vmcode_property_get(njs_vm_t *vm, nj /* string[n]. */ - num = njs_value_to_number(property); - index = (int32_t) num; - - if (index >= 0 && index == num) { + index = (int32_t) njs_value_to_index(property); + + if (nxt_fast_path(index >= 0)) { slice.start = index; slice.length = 1; slice.string_length = njs_string_prop(&string, object); @@ -943,11 +941,9 @@ static nxt_noinline njs_ret_t njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *object, njs_value_t *property) { - double num; uint32_t index; uint32_t (*hash)(const void *, size_t); njs_ret_t ret; - nxt_bool_t valid; njs_extern_t *ext; njs_object_t *obj; njs_function_t *function; @@ -978,22 +974,15 @@ njs_property_query(njs_vm_t *vm, njs_pro if (nxt_fast_path(!njs_is_null_or_void_or_boolean(property))) { if (nxt_fast_path(njs_is_primitive(property))) { - num = njs_value_to_number(property); + index = njs_value_to_index(property); + + if (nxt_fast_path(index < NJS_ARRAY_MAX_LENGTH)) { + return njs_array_property_query(vm, pq, object, index); + } } else { return NJS_TRAP_PROPERTY; } - - if (nxt_fast_path(num >= 0)) { - index = (uint32_t) num; - - valid = nxt_expect(1, (index < NJS_ARRAY_MAX_LENGTH - && (double) index == num)); - - if (valid) { - return njs_array_property_query(vm, pq, object, index); - } - } } /* Fall through. */ @@ -3026,7 +3015,7 @@ njs_vmcode_number_primitive(njs_vm_t *vm num = NAN; if (njs_is_string(value)) { - num = njs_string_to_number(value, 1); + num = njs_string_to_number(value, 0); } njs_number_set(value, num); @@ -3079,7 +3068,7 @@ njs_vmcode_number_argument(njs_vm_t *vm, num = NAN; if (njs_is_string(value)) { - num = njs_string_to_number(value, 1); + num = njs_string_to_number(value, 0); } njs_number_set(value, num); diff -r 4e2da602c2a3 -r a38c33e9f728 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon May 29 22:13:21 2017 +0300 +++ b/njs/test/njs_unit_test.c Tue May 30 19:35:08 2017 +0300 @@ -115,6 +115,29 @@ static njs_unit_test_t njs_test[] = { nxt_string("+1\n"), nxt_string("1") }, + /* Hex Numbers. */ + + { nxt_string("0x0"), + nxt_string("0") }, + + { nxt_string("-0x1"), + nxt_string("-1") }, + + { nxt_string("0xffFF"), + nxt_string("65535") }, + + { nxt_string("0X0000BEEF"), + nxt_string("48879") }, + + { nxt_string("0x"), + nxt_string("SyntaxError: Unexpected token \"\" in 1") }, + + { nxt_string("0xffff."), + nxt_string("SyntaxError: Unexpected token \"\" in 1") }, + + { nxt_string("0x12g"), + nxt_string("SyntaxError: Unexpected token \"g\" in 1") }, + { nxt_string(""), nxt_string("undefined") }, @@ -127,6 +150,17 @@ static njs_unit_test_t njs_test[] = { nxt_string("\n +1"), nxt_string("1") }, + /* Indexes. */ + + { nxt_string("var a = []; a[-1] = 2; a[-1] == a['-1']"), + nxt_string("true") }, + + { nxt_string("var a = []; a[Infinity] = 2; a[Infinity] == a['Infinity']"), + nxt_string("true") }, + + { nxt_string("var a = []; a[NaN] = 2; a[NaN] == a['NaN']"), + nxt_string("true") }, + /* Number.toString(radix) method. */ { nxt_string("0..toString(2)"), @@ -153,6 +187,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("81985529216486895..toString(16)"), nxt_string("123456789abcdf0") }, + { nxt_string("0xffff.toString(16)"), + nxt_string("ffff") }, + { nxt_string("1845449130881..toString(36)"), nxt_string("njscript") }, @@ -220,12 +257,18 @@ static njs_unit_test_t njs_test[] = { nxt_string("1 + ''"), nxt_string("1") }, + { nxt_string("0xA + ''"), + nxt_string("10") }, + { nxt_string("undefined + undefined"), nxt_string("NaN") }, { nxt_string("1.2 + 5.7"), nxt_string("6.9") }, + { nxt_string("0xf + 1"), + nxt_string("16") }, + { nxt_string("1 + 1 + '2' + 1 + 1"), nxt_string("2211") }, @@ -235,6 +278,30 @@ static njs_unit_test_t njs_test[] = { nxt_string("1.2 + -'5.7'"), nxt_string("-4.5") }, + { nxt_string("1.2 - '-5.7'"), + nxt_string("6.9") }, + + { nxt_string("5 - ' \t 12 \t'"), + nxt_string("-7") }, + + { nxt_string("5 - '12zz'"), + nxt_string("NaN") }, + + { nxt_string("5 - '0x2'"), + nxt_string("3") }, + + { nxt_string("5 - '-0x2'"), + nxt_string("7") }, + + { nxt_string("5 - '\t 0x2 \t'"), + nxt_string("3") }, + + { nxt_string("5 - '0x2 z'"), + nxt_string("NaN") }, + + { nxt_string("5 - '0x'"), + nxt_string("NaN") }, + { nxt_string("1 + +'3'"), nxt_string("4") }, @@ -2334,6 +2401,18 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [ 1, 2, 3 ]; a[0] +' '+ a[1] +' '+ a[2] +' '+ a[3]"), nxt_string("1 2 3 undefined") }, + { nxt_string("var a = [ 5, 6, 7 ]; a['1']"), + nxt_string("6") }, + + { nxt_string("var a = [ 5, 6, 7 ]; a['01']"), + nxt_string("undefined") }, + + { nxt_string("var a = [ 5, 6, 7 ]; a[0x1]"), + nxt_string("6") }, + + { nxt_string("var a = [ 5, 6, 7 ]; a['0x1']"), + nxt_string("undefined") }, + { nxt_string("[] - 2"), nxt_string("-2") }, @@ -3145,6 +3224,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("'\\u03B'"), nxt_string("SyntaxError: Invalid Unicode code point \"\\u03B\" in 1") }, + { nxt_string("'\\u03BG'"), + nxt_string("SyntaxError: Invalid Unicode code point \"\\u03BG\" in 1") }, + + { nxt_string("'\\u03B '"), + nxt_string("SyntaxError: Invalid Unicode code point \"\\u03B \" in 1") }, + { nxt_string("'\\u{61}\\u{3B1}\\u{20AC}'"), nxt_string("a??") }, @@ -3449,6 +3534,30 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abcdef'[8]"), nxt_string("undefined") }, + { nxt_string("'abcdef'['1']"), + nxt_string("b") }, + + { nxt_string("'abcdef'[' 1']"), + nxt_string("undefined") }, + + { nxt_string("'abcdef'['1 ']"), + nxt_string("undefined") }, + + { nxt_string("'abcdef'['']"), + nxt_string("undefined") }, + + { nxt_string("'abcdef'['-']"), + nxt_string("undefined") }, + + { nxt_string("'abcdef'['-1']"), + nxt_string("undefined") }, + + { nxt_string("'abcdef'['01']"), + nxt_string("undefined") }, + + { nxt_string("'abcdef'['0x01']"), + nxt_string("undefined") }, + { nxt_string("var a = 'abcdef', b = 1 + 2; a[b]"), nxt_string("d") }, @@ -7077,6 +7186,21 @@ static njs_unit_test_t njs_test[] = { nxt_string("parseFloat('12345abc')"), nxt_string("12345") }, + { nxt_string("parseFloat('0x')"), + nxt_string("0") }, + + { nxt_string("parseFloat('0xff')"), + nxt_string("0") }, + + { nxt_string("parseFloat('Infinity')"), + nxt_string("Infinity") }, + + { nxt_string("parseFloat(' Infinityzz')"), + nxt_string("Infinity") }, + + { nxt_string("parseFloat('Infinit')"), + nxt_string("NaN") }, + /* Trick: number to boolean. */ { nxt_string("var a = 0; !!a"), From piotrsikora at google.com Tue May 30 21:21:05 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 30 May 2017 14:21:05 -0700 Subject: [PATCH] HTTP/2: add debug logging of control frames In-Reply-To: References: <06d6418afe6e73604aea.1491275620@piotrsikora.sfo.corp.google.com> <1619400.xHm06BXEHk@vbart-workstation> <3132219.tz8ccajtOM@vbart-workstation> Message-ID: Hey Valentin, > What do you suggest instead? All 3 params in the same line? > > http2 send SETTINGS frame MAX_CONCURRENT_STREAMS:%ui > INITIAL_WINDOW_SIZE:%uz MAX_FRAME_SIZE:%ud > > What about receiving part, then? Do you want to put all 6 params in > the same line? > > http2 recv SETTINGS frame HEADER_TABLE_SIZE:%ui (ignored) > ENABLE_PUSH:%ui (ignored) MAX_CONCURRENT_STREAMS:%ui (ignored) > INITIAL_WINDOW_SIZE:%ui MAX_FRAME_SIZE:%ui MAX_HEADER_LIST_SIZE:%ui > (ignored) > > It makes this way less readable, IMHO. Ping. Best regards, Piotr Sikora From piotrsikora at google.com Tue May 30 21:22:45 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 30 May 2017 14:22:45 -0700 Subject: [PATCH 1 of 4] HTTP/2: emit new frames only after applying all SETTINGS params In-Reply-To: <07adf0a7009c3244de4b.1493074103@piotrsikora.sfo.corp.google.com> References: <07adf0a7009c3244de4b.1493074103@piotrsikora.sfo.corp.google.com> Message-ID: Hey, > # HG changeset patch > # User Piotr Sikora > # Date 1493073310 25200 > # Mon Apr 24 15:35:10 2017 -0700 > # Node ID 07adf0a7009c3244de4b795c0c06927f4316a87f > # Parent 2c4dbcd6f2e4c9c2a1eb8dc1f0d39c99975ae208 > HTTP/2: emit new frames only after applying all SETTINGS params. > > Previously, new frames could be emitted in the middle of applying > new (and already acknowledged) SETTINGS params, which is illegal. > > Signed-off-by: Piotr Sikora Ping (on the whole patchset). Best regards, Piotr Sikora From sepherosa at gmail.com Wed May 31 02:28:41 2017 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Wed, 31 May 2017 10:28:41 +0800 Subject: [PATCH] worker_cpu_affinity support for DragonFlyBSD In-Reply-To: <20170529140454.GS55433@mdounin.ru> References: <20170526160401.GG55433@mdounin.ru> <20170529140454.GS55433@mdounin.ru> Message-ID: On Mon, May 29, 2017 at 10:04 PM, Maxim Dounin wrote: > Hello! > > On Sat, May 27, 2017 at 09:13:55AM +0800, Sepherosa Ziehau wrote: > >> Hi Maxim, >> >> Your patch works. Thank you! > > Committed, thanks for testing. Thank you! -- Tomorrow Will Never Die From xeioex at nginx.com Wed May 31 11:56:02 2017 From: xeioex at nginx.com (Dmitry Volyntsev) Date: Wed, 31 May 2017 14:56:02 +0300 Subject: [njs] Lexer support for hexadecimal literal values. In-Reply-To: References: Message-ID: Hi, Paulo the support for hexadecimal literal values was committed in http://hg.nginx.org/njs/rev/a38c33e9f728 Thank you for prodding. On 21.05.2017 20:52, Paulo Pacheco wrote: > # HG changeset patch > # User Paulo Pacheco > > # Date 1495388206 0 > # Sun May 21 17:36:46 2017 +0000 > # Node ID 22db6b6a3a0eebff8453fb22035628410c05c5c8 > # Parent 96fda9957427e1ea78d0096b019a3f3183db7346 > [njs] Lexer support for hexadecimal literal values. > > diff -r 96fda9957427 -r 22db6b6a3a0e njs/njs_lexer.c > --- a/njs/njs_lexer.c Wed Apr 19 17:48:56 2017 +0300 > +++ b/njs/njs_lexer.c Sun May 21 17:36:46 2017 +0000 > @@ -19,7 +19,7 @@ > #include > #include > #include > - > +#include > > typedef struct njs_lexer_multi_s njs_lexer_multi_t; > > @@ -539,10 +539,28 @@ > { > u_char c, *p; > double num, frac, scale; > + char *endptr; > > /* TODO: "1e2" */ > > p = lexer->start; > + > + /* Hexadecimal literal values */ > + if ( (lexer->end - lexer->start) > 2 > + && (*p == 'x' || *p == 'X') > + && (lexer->prev_token > 0 > + || ((lexer->start - 1) == lexer->text.start) > + ) > + && (*(p-1) == '0')) { > + > + lexer->number = strtod((const char *) p-1, &endptr); > + if ((u_char *) endptr <= lexer->end) { > + lexer->start = (u_char *) endptr; > + return NJS_TOKEN_NUMBER; > + } > + lexer->number = 0; > + } > + > c = p[-1]; > > /* Values below '0' become >= 208. */ > diff -r 96fda9957427 -r 22db6b6a3a0e njs/test/njs_unit_test.c > --- a/njs/test/njs_unit_test.c Wed Apr 19 17:48:56 2017 +0300 > +++ b/njs/test/njs_unit_test.c Sun May 21 17:36:46 2017 +0000 > @@ -112,6 +112,18 @@ > { nxt_string("+1"), > nxt_string("1") }, > > + { nxt_string("var a = 0x01; a"), > + nxt_string("1") }, > + > + { nxt_string("var x = 0xffff; x"), > + nxt_string("65535") }, > + > + { nxt_string("0x01"), > + nxt_string("1") }, > + > + { nxt_string("0xffff"), > + nxt_string("65535") }, > + > { nxt_string("+1\n"), > nxt_string("1") }, > > > ---------------------------------- CUT HERE > -------------------------------------- > Paulo Pacheco | ????? ?????? > > > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > From fooinha at gmail.com Wed May 31 13:19:03 2017 From: fooinha at gmail.com (Paulo Pacheco) Date: Wed, 31 May 2017 14:19:03 +0100 Subject: [njs] Lexer support for hexadecimal literal values. In-Reply-To: References: Message-ID: Hi ??????? Thanx for this. This is great. I'm going to update and test. Best regards to all nginx team, -------------------------------------- Paulo Pacheco | ????? ?????? On Wed, May 31, 2017 at 12:56 PM, Dmitry Volyntsev wrote: > Hi, Paulo > > the support for hexadecimal literal values was committed in > http://hg.nginx.org/njs/rev/a38c33e9f728 > > Thank you for prodding. > > On 21.05.2017 20:52, Paulo Pacheco wrote: > >> # HG changeset patch >> # User Paulo Pacheco > >> >> # Date 1495388206 0 >> # Sun May 21 17:36:46 2017 +0000 >> # Node ID 22db6b6a3a0eebff8453fb22035628410c05c5c8 >> # Parent 96fda9957427e1ea78d0096b019a3f3183db7346 >> [njs] Lexer support for hexadecimal literal values. >> >> diff -r 96fda9957427 -r 22db6b6a3a0e njs/njs_lexer.c >> --- a/njs/njs_lexer.c Wed Apr 19 17:48:56 2017 +0300 >> +++ b/njs/njs_lexer.c Sun May 21 17:36:46 2017 +0000 >> @@ -19,7 +19,7 @@ >> #include >> #include >> #include >> - >> +#include >> >> typedef struct njs_lexer_multi_s njs_lexer_multi_t; >> >> @@ -539,10 +539,28 @@ >> { >> u_char c, *p; >> double num, frac, scale; >> + char *endptr; >> >> /* TODO: "1e2" */ >> >> p = lexer->start; >> + >> + /* Hexadecimal literal values */ >> + if ( (lexer->end - lexer->start) > 2 >> + && (*p == 'x' || *p == 'X') >> + && (lexer->prev_token > 0 >> + || ((lexer->start - 1) == lexer->text.start) >> + ) >> + && (*(p-1) == '0')) { >> + >> + lexer->number = strtod((const char *) p-1, &endptr); >> + if ((u_char *) endptr <= lexer->end) { >> + lexer->start = (u_char *) endptr; >> + return NJS_TOKEN_NUMBER; >> + } >> + lexer->number = 0; >> + } >> + >> c = p[-1]; >> >> /* Values below '0' become >= 208. */ >> diff -r 96fda9957427 -r 22db6b6a3a0e njs/test/njs_unit_test.c >> --- a/njs/test/njs_unit_test.c Wed Apr 19 17:48:56 2017 +0300 >> +++ b/njs/test/njs_unit_test.c Sun May 21 17:36:46 2017 +0000 >> @@ -112,6 +112,18 @@ >> { nxt_string("+1"), >> nxt_string("1") }, >> >> + { nxt_string("var a = 0x01; a"), >> + nxt_string("1") }, >> + >> + { nxt_string("var x = 0xffff; x"), >> + nxt_string("65535") }, >> + >> + { nxt_string("0x01"), >> + nxt_string("1") }, >> + >> + { nxt_string("0xffff"), >> + nxt_string("65535") }, >> + >> { nxt_string("+1\n"), >> nxt_string("1") }, >> >> >> ---------------------------------- CUT HERE >> -------------------------------------- >> Paulo Pacheco | ????? ?????? >> >> >> >> >> _______________________________________________ >> 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 zelenkov at nginx.com Wed May 31 17:26:39 2017 From: zelenkov at nginx.com (Andrey Zelenkov) Date: Wed, 31 May 2017 17:26:39 +0000 Subject: [njs] Fixed parseInt() zero radix parsing. Message-ID: details: http://hg.nginx.org/njs/rev/b592f24c9ac6 branches: changeset: 348:b592f24c9ac6 user: Andrey Zelenkov date: Wed May 31 20:25:44 2017 +0300 description: Fixed parseInt() zero radix parsing. diffstat: njs/njs_number.c | 16 ++++++++++------ njs/test/njs_unit_test.c | 6 ++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diffs (49 lines): diff -r a38c33e9f728 -r b592f24c9ac6 njs/njs_number.c --- a/njs/njs_number.c Tue May 30 19:35:08 2017 +0300 +++ b/njs/njs_number.c Wed May 31 20:25:44 2017 +0300 @@ -733,19 +733,23 @@ njs_number_parse_int(njs_vm_t *vm, njs_v } test_prefix = (end - p > 1); + radix = 0; if (nargs > 2) { radix = args[2].data.u.number; - if (radix < 2 || radix > 36) { - goto done; - } + if (radix != 0) { + if (radix < 2 || radix > 36) { + goto done; + } - if (radix != 16) { - test_prefix = 0; + if (radix != 16) { + test_prefix = 0; + } } + } - } else { + if (radix == 0) { radix = 10; } diff -r a38c33e9f728 -r b592f24c9ac6 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue May 30 19:35:08 2017 +0300 +++ b/njs/test/njs_unit_test.c Wed May 31 20:25:44 2017 +0300 @@ -7144,6 +7144,12 @@ static njs_unit_test_t njs_test[] = { nxt_string("parseInt('12345abc')"), nxt_string("12345") }, + { nxt_string("parseInt('123', 0)"), + nxt_string("123") }, + + { nxt_string("parseInt('0XaBc', 0)"), + nxt_string("2748") }, + { nxt_string("parseInt('1010', 2)"), nxt_string("10") }, From zelenkov at nginx.com Wed May 31 17:37:57 2017 From: zelenkov at nginx.com (Andrey Zelenkov) Date: Wed, 31 May 2017 17:37:57 +0000 Subject: [njs] Fixed parseInt() leading white space ignoring. Message-ID: details: http://hg.nginx.org/njs/rev/559d256dd65b branches: changeset: 349:559d256dd65b user: Andrey Zelenkov date: Wed May 31 20:36:01 2017 +0300 description: Fixed parseInt() leading white space ignoring. diffstat: njs/njs_number.c | 3 +-- njs/test/njs_unit_test.c | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diffs (28 lines): diff -r b592f24c9ac6 -r 559d256dd65b njs/njs_number.c --- a/njs/njs_number.c Wed May 31 20:25:44 2017 +0300 +++ b/njs/njs_number.c Wed May 31 20:36:01 2017 +0300 @@ -709,10 +709,9 @@ njs_number_parse_int(njs_vm_t *vm, njs_v if (nargs > 1) { (void) njs_string_prop(&string, &args[1]); - p = string.start; end = string.start + string.size; - while (p < end) { + for (p = string.start; p < end; p++) { if (*p != ' ') { goto found; } diff -r b592f24c9ac6 -r 559d256dd65b njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed May 31 20:25:44 2017 +0300 +++ b/njs/test/njs_unit_test.c Wed May 31 20:36:01 2017 +0300 @@ -7150,6 +7150,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("parseInt('0XaBc', 0)"), nxt_string("2748") }, + { nxt_string("parseInt(' 123')"), + nxt_string("123") }, + { nxt_string("parseInt('1010', 2)"), nxt_string("10") }, From piotrsikora at google.com Wed May 31 20:54:00 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 31 May 2017 13:54:00 -0700 Subject: [PATCH] Headers filter: style Message-ID: <057ec63be834988b6435.1496264040@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1496263895 25200 # Wed May 31 13:51:35 2017 -0700 # Node ID 057ec63be834988b6435b4ef64a1c3bd0cc23959 # Parent ab6ef3037840393752d82fac01ea1eb4f972301c Headers filter: style. Signed-off-by: Piotr Sikora diff -r ab6ef3037840 -r 057ec63be834 src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -98,7 +98,7 @@ static ngx_command_t ngx_http_headers_f ngx_http_headers_expires, NGX_HTTP_LOC_CONF_OFFSET, 0, - NULL}, + NULL }, { ngx_string("add_header"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF @@ -106,7 +106,7 @@ static ngx_command_t ngx_http_headers_f ngx_http_headers_add, NGX_HTTP_LOC_CONF_OFFSET, 0, - NULL}, + NULL }, ngx_null_command }; From piotrsikora at google.com Wed May 31 20:54:05 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 31 May 2017 13:54:05 -0700 Subject: [PATCH] Upstream: style Message-ID: # HG changeset patch # User Piotr Sikora # Date 1496263896 25200 # Wed May 31 13:51:36 2017 -0700 # Node ID e7219bf8bc3781d3912a951f09553bb2f0a53b70 # Parent ab6ef3037840393752d82fac01ea1eb4f972301c Upstream: style. Signed-off-by: Piotr Sikora diff -r ab6ef3037840 -r e7219bf8bc37 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2729,7 +2729,7 @@ ngx_http_upstream_process_body_in_memory rev = c->read; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http upstream process body on memory"); + "http upstream process body in memory"); if (rev->timedout) { ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); From piotrsikora at google.com Wed May 31 22:48:34 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 31 May 2017 15:48:34 -0700 Subject: [PATCH] HTTP/2: reject HTTP/2 requests without ":scheme" pseudo-header In-Reply-To: <17543215.oua5ZIKEOg@vbart-workstation> References: <6bb029b1df11662ba11e.1490517677@piotrsikora.sfo.corp.google.com> <10964631.oCTdTOokgi@vbart-workstation> <17543215.oua5ZIKEOg@vbart-workstation> Message-ID: Hey Valentin, > As the 1.11 branch is going to be stable soon, it's a good idea to postpone > any changes that explicitly affect interoperability (at least till 1.13). Any thoughts on this now that 1.12 branched? Best regards, Piotr Sikora From piotrsikora at google.com Wed May 31 22:50:21 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 31 May 2017 15:50:21 -0700 Subject: [PATCH] HTTP/2: reject HTTP/2 requests with "Connection" header In-Reply-To: References: Message-ID: Hey, > # HG changeset patch > # User Piotr Sikora > # Date 1490516709 25200 > # Sun Mar 26 01:25:09 2017 -0700 > # Node ID b8daccea5fde213d4b7a10fa9f57070ab3b6a1ec > # Parent 22be63bf21edaa1b8ea916c7d8cd4e5fe4892061 > HTTP/2: reject HTTP/2 requests with "Connection" header. > > While there, populate r->headers_in.connection. > > Signed-off-by: Piotr Sikora Ping. Best regards, Piotr Sikora From piotrsikora at google.com Wed May 31 23:13:56 2017 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 31 May 2017 16:13:56 -0700 Subject: [PATCH] HTTP/2: reject HTTP/2 requests with invalid "TE" header value Message-ID: # HG changeset patch # User Piotr Sikora # Date 1496272340 25200 # Wed May 31 16:12:20 2017 -0700 # Node ID a8050d50338bf127d57f820744a498517bf44b68 # Parent ab6ef3037840393752d82fac01ea1eb4f972301c HTTP/2: reject HTTP/2 requests with invalid "TE" header value. Signed-off-by: Piotr Sikora diff -r ab6ef3037840 -r a8050d50338b src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -27,6 +27,8 @@ static ngx_int_t ngx_http_process_host(n ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); +static ngx_int_t ngx_http_process_te(ngx_http_request_t *r, + ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); @@ -128,6 +130,10 @@ ngx_http_header_t ngx_http_headers_in[] offsetof(ngx_http_headers_in_t, if_range), ngx_http_process_unique_header_line }, + { ngx_string("TE"), + offsetof(ngx_http_headers_in_t, te), + ngx_http_process_te }, + { ngx_string("Transfer-Encoding"), offsetof(ngx_http_headers_in_t, transfer_encoding), ngx_http_process_header_line }, @@ -1690,6 +1696,41 @@ ngx_http_process_connection(ngx_http_req static ngx_int_t +ngx_http_process_te(ngx_http_request_t *r, ngx_table_elt_t *h, + ngx_uint_t offset) +{ + if (r->headers_in.te == NULL) { + r->headers_in.te = h; + } + + if (r->http_version <= NGX_HTTP_VERSION_11) { + return NGX_OK; + } + + if (h->value.len == sizeof("trailers") - 1 + && ngx_memcmp(h->value.data, "trailers", sizeof("trailers") - 1) == 0) + { + return NGX_OK; + } + +#if (NGX_HTTP_V2) + + if (r->http_version >= NGX_HTTP_VERSION_20) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent HTTP/2 request with invalid header value: " + "\"TE: %V\"", &h->value); + + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + return NGX_ERROR; + } + +#endif + + return NGX_OK; +} + + +static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { diff -r ab6ef3037840 -r a8050d50338b src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -196,6 +196,7 @@ typedef struct { ngx_table_elt_t *range; ngx_table_elt_t *if_range; + ngx_table_elt_t *te; ngx_table_elt_t *transfer_encoding; ngx_table_elt_t *expect; ngx_table_elt_t *upgrade;