Quantcast
Channel: Nginx Forum
Viewing all 53287 articles
Browse latest View live

Re: Using proxy_cache_background_update

$
0
0
Hello!

On Mon, Feb 27, 2017 at 05:53:30AM -0500, jeanpaul wrote:

> I verified the patch and it seems to work!
> Thanks for your prompt solution on this.

Committed, thanks for testing.
http://hg.nginx.org/nginx/rev/8b7fd958c59f

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

[nginx] Fixed background update with "if".

$
0
0
details: http://hg.nginx.org/nginx/rev/8b7fd958c59f
branches:
changeset: 6920:8b7fd958c59f
user: Maxim Dounin <mdounin@mdounin.ru>
date: Mon Feb 27 22:36:15 2017 +0300
description:
Fixed background update with "if".

Cloned subrequests should inherit r->content_handler. This way they will
be able to use the same location configuration as the original request
if there are "if" directives in the configuration.

Without r->content_handler inherited, the following configuration tries
to access a static file in the update request:

location / {
set $true 1;
if ($true) {
# nothing
}

proxy_pass http://backend;
proxy_cache one;
proxy_cache_use_stale updating;
proxy_cache_background_update on;
}

See http://mailman.nginx.org/pipermail/nginx/2017-February/053019.html for
initial report.

diffstat:

src/http/ngx_http_core_module.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diffs (11 lines):

diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2571,6 +2571,7 @@ ngx_http_subrequest(ngx_http_request_t *
sr->method_name = r->method_name;
sr->loc_conf = r->loc_conf;
sr->valid_location = r->valid_location;
+ sr->content_handler = r->content_handler;
sr->phase_handler = r->phase_handler;
sr->write_event_handler = ngx_http_core_run_phases;

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

set_real_ip_from,real_ip_header directive in ngx_http_realip_module

$
0
0
Hello,
I tried to limit an IPv4 Address with ngx_http_limit_req module and
ngx_realip_module via Akamai would send True-Client-IP headers.

According to the document ngx_http_readip_module(
http://nginx.org/en/docs/http/ngx_http_realip_module.html),
we can write set_real_ip_from and real-_ip_header directive in http,
server, location context.

But, in the above case(ngx_http_limit_req module is defined the key in http
context), directives on ngx_http_realip_module must be defined before the
keys(a.k.a replaced IPv4 adress by ngx_http_realip_module) and followed
limit_req_zone directive in http context.

I think it better that the document explained ngx_http_realip_module
directive is configured before ngx_http_limit_req module configuration.

Our environment is Amazon Linux on AWS EC2 package and nginx version was
1.10.1.

If you already plan to improve the documentation and you know, please let
me know and I will check it out.

Thanks.
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

[PATCH] Resolver: parse hosts file entries

$
0
0
Hello,

Here is an attempt at parsing and caching the hosts entries from
/etc/hosts. I believe that the resolver should provide such an option to
allow:

- saving DNS lookups
- avoiding confusion from users who expect it to be resolved
- the current implementation now self-documents whether the hosts file
is used for a particular resolver or not

Please let me know if this is of any interest.

--
Thibault

# HG changeset patch
# User Thibault Charbonnier <thibaultcha@fastmail.com>
# Date 1488252201 28800
# Mon Feb 27 19:23:21 2017 -0800
# Branch resolve-hostsfile
# Node ID 91ef480a020bae132506052ca567fef2c4422705
# Parent 640f035293959b2d4b0ba5939d954bc517f57f77
Resolver: parse hosts file entries

The resolver option can now take an optional 'hosts=<path>' option, such as:

resolver 8.8.4.4 hosts=/etc/hosts;

Hosts parsed from the hosts file are considered valid forever. The behavior
tries to be conservative, and only parses the hosts file when the option is
provided, to enforce backwards compatibility.

diff -r 640f03529395 -r 91ef480a020b src/core/ngx_resolver.c
--- a/src/core/ngx_resolver.c Fri Jan 27 19:06:35 2017 +0300
+++ b/src/core/ngx_resolver.c Mon Feb 27 19:23:21 2017 -0800
@@ -9,11 +9,12 @@
#include <ngx_core.h>
#include <ngx_event.h>

-
-#define NGX_RESOLVER_UDP_SIZE 4096
-
-#define NGX_RESOLVER_TCP_RSIZE (2 + 65535)
-#define NGX_RESOLVER_TCP_WSIZE 8192
+#define NGX_RESOLVER_HOSTSFILE_SIZE 4096
+
+#define NGX_RESOLVER_UDP_SIZE 4096
+
+#define NGX_RESOLVER_TCP_RSIZE (2 + 65535)
+#define NGX_RESOLVER_TCP_WSIZE 8192


typedef struct {
@@ -120,6 +121,8 @@
ngx_resolver_node_t *rn);
static void ngx_resolver_srv_names_handler(ngx_resolver_ctx_t *ctx);
static ngx_int_t ngx_resolver_cmp_srvs(const void *one, const void *two);
+static ngx_int_t ngx_resolver_parse_hostsfile(ngx_conf_t *cf,
ngx_resolver_t *r,
+ ngx_str_t filename);

#if (NGX_HAVE_INET6)
static void ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t
*temp,
@@ -128,7 +131,6 @@
struct in6_addr *addr, uint32_t hash);
#endif

-
ngx_resolver_t *
ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
{
@@ -243,6 +245,24 @@
}
#endif

+ if (ngx_strncmp(names[i].data, "hosts=", 6) == 0) {
+ r->hostsfile.len = names[i].len - 6;
+
+ if (r->hostsfile.len == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter: %V", &names[i]);
+ return NULL;
+ }
+
+ r->hostsfile.data = ngx_resolver_dup(r, names[i].data + 6,
+ r->hostsfile.len + 1);
+ if (r->hostsfile.data == NULL) {
+ return NULL;
+ }
+
+ continue;
+ }
+
ngx_memzero(&u, sizeof(ngx_url_t));

u.url = names[i];
@@ -273,6 +293,13 @@
}
}

+ if (r->hostsfile.len > 0
+ && ngx_resolver_parse_hostsfile(cf, r, r->hostsfile)
+ != NGX_OK)
+ {
+ return NULL;
+ }
+
return r;
}

@@ -4660,3 +4687,264 @@

return p1 - p2;
}
+
+
+static ngx_int_t
+ngx_resolver_parse_hostsfile(ngx_conf_t *cf, ngx_resolver_t *r,
+ ngx_str_t filename)
+{
+ off_t file_size;
+ u_char ch;
+ u_char *start;
+ size_t len;
+ ssize_t n, size;
+ ngx_int_t rc;
+ ngx_str_t s;
+ ngx_fd_t fd;
+ ngx_buf_t b;
+ ngx_file_t file;
+ in_addr_t addr;
+ ngx_resolver_node_t *rn;
+ enum {
+ scan_line = 0,
+ scan_skipline,
+ scan_addr,
+ scan_hosts,
+ scan_name
+ } state;
+
+ b.start = NULL;
+ s.data = NULL;
+ s.len = 0;
+ rn = NULL;
+
+ fd = ngx_open_file(filename.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+ if (fd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", filename.data);
+ return NGX_ERROR;
+ }
+
+ ngx_memzero(&file, sizeof(ngx_file_t));
+
+ if (ngx_fd_info(fd, &file.info) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_fd_info_n " \"%s\" failed", filename.data);
+ goto fail;
+ }
+
+ file.fd = fd;
+ file.log = cf->log;
+ file.name.len = filename.len;
+ file.name.data = filename.data;
+ file.offset = 0;
+
+ b.start = ngx_resolver_alloc(r, NGX_RESOLVER_HOSTSFILE_SIZE);
+ if (b.start == NULL) {
+ goto fail;
+ }
+
+ b.pos = b.start;
+ b.last = b.start;
+ b.end = b.last + NGX_RESOLVER_HOSTSFILE_SIZE;
+ b.temporary = 1;
+
+ start = b.pos;
+ state = scan_line;
+ file_size = ngx_file_size(&file.info);
+
+ for ( ;; ) {
+
+ if (b.pos >= b.last) {
+ len = b.pos - start;
+
+ if (len) {
+ ngx_memmove(b.start, start, len);
+ }
+
+ size = (ssize_t) (file_size - file.offset);
+
+ if (size > b.end - (b.start + len)) {
+ size = b.end - (b.start + len);
+
+ } else if (size == 0) {
+ rc = NGX_OK;
+ goto done;
+ }
+
+ n = ngx_read_file(&file, b.start + len, size, file.offset);
+ if (n == NGX_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_read_file_n, " \"%s\" failed",
+ filename.data);
+ goto fail;
+ }
+
+ if (n != size) {
+ ngx_log_error(NGX_LOG_ERR, cf->log, ngx_errno,
+ ngx_read_file_n, " returned only %z bytes "
+ "instead of %z", n, size);
+ goto fail;
+ }
+
+ b.pos = b.start + len;
+ b.last = b.pos + n;
+ start = b.start;
+ }
+
+ ch = *b.pos;
+
+ switch (state) {
+
+ case scan_line:
+ if (ch == ' ') {
+ break;
+ }
+
+ if (ch == '#') {
+ state = scan_skipline;
+ break;
+ }
+
+ start = b.pos;
+ state = scan_addr;
+ break;
+
+ case scan_skipline:
+ if (ch == LF || ch == CR) {
+ state = scan_line;
+ }
+
+ break;
+
+ case scan_addr:
+ if (ch == LF || ch == CR) {
+ state = scan_line;
+ break;
+ }
+
+ if (ch == ' ' || ch == '\t') {
+ if (s.data) {
+ ngx_resolver_free(r, s.data);
+ }
+
+ s.len = b.pos - start;
+
+ s.data = ngx_resolver_dup(r, start, s.len);
+ if (s.data == NULL) {
+ goto fail;
+ }
+
+ state = scan_hosts;
+ }
+
+ break;
+
+ case scan_hosts:
+ if (ch == LF || ch == CR) {
+ state = scan_line;
+ break;
+ }
+
+ if (ch == ' ' || ch == '\t') {
+ break;
+ }
+
+ start = b.pos;
+ state = scan_name;
+ break;
+
+ case scan_name:
+ if (ch == ' ' || ch == '\t' || ch == LF || ch == CR) {
+ rn = ngx_resolver_calloc(r, sizeof(ngx_resolver_node_t));
+ if (rn == NULL) {
+ goto fail;
+ }
+
+ rn->nlen = b.pos - start;
+
+ rn->name = ngx_resolver_dup(r, start, rn->nlen);
+ if (rn->name == NULL) {
+ goto fail;
+ }
+
+ rn->ttl = NGX_MAX_UINT32_VALUE;
+ rn->valid = NGX_MAX_UINT32_VALUE;
+ rn->expire = NGX_MAX_UINT32_VALUE;
+ rn->node.key = ngx_crc32_short(rn->name, rn->nlen);
+
+ if (ngx_strlchr(s.data,
+ s.data + s.len, ':') != NULL)
+ {
+
+#if (NGX_HAVE_INET6)
+ if (!r->ipv6
+ || ngx_inet6_addr(s.data, s.len,
+ rn->u6.addr6.s6_addr) != NGX_OK)
+ {
+ ngx_resolver_free_node(r, rn);
+ state = scan_skipline;
+ break;
+ }
+
+ rn->naddrs6 = 1;
+#endif
+
+ } else {
+ addr = ngx_inet_addr(s.data, s.len);
+ if (addr == INADDR_NONE) {
+ ngx_resolver_free_node(r, rn);
+ state = scan_skipline;
+ break;
+ }
+
+ rn->naddrs = 1;
+ rn->u.addr = addr;
+ }
+
+ ngx_rbtree_insert(&r->name_rbtree, &rn->node);
+
+ ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
+
+ if (ch == LF || ch == CR) {
+ state = scan_line;
+ break;
+ }
+
+ state = scan_hosts;
+ }
+
+ break;
+ }
+
+ b.pos++;
+ }
+
+fail:
+
+ rc = NGX_ERROR;
+
+done:
+
+ if (s.data) {
+ ngx_resolver_free(r, s.data);
+ }
+
+ if (b.start) {
+ ngx_resolver_free(r, b.start);
+ }
+
+ if (ngx_close_file(fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_close_file_n, " \"%s\" failed",
+ filename.data);
+ rc = NGX_ERROR;
+ }
+
+ if (rc == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
diff -r 640f03529395 -r 91ef480a020b src/core/ngx_resolver.h
--- a/src/core/ngx_resolver.h Fri Jan 27 19:06:35 2017 +0300
+++ b/src/core/ngx_resolver.h Mon Feb 27 19:23:21 2017 -0800
@@ -146,6 +146,8 @@


struct ngx_resolver_s {
+ ngx_str_t hostsfile;
+
/* has to be pointer because of "incomplete type" */
ngx_event_t *event;
void *dummy;

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

Re: [PATCH] Resolver: parse hosts file entries

$
0
0
On 2/27/17 7:45 PM, Thibault Charbonnier wrote:
> + if (r->hostsfile.len > 0
> + && ngx_resolver_parse_hostsfile(cf, r, r->hostsfile)

My bad, the third argument here can probably be removed. I moved the
hosts file path to the resolver struct at some point in order to
_eventually_ implement some sort or reloading in the future.

> + != NGX_OK)
> + {
> + return NULL;
> + }
> +
> return r;
> }
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: nginx stopping abruptly at fix time (2:00 am) repeatedly on Cent OS 7.2

$
0
0
Hi Anoop and B.R ... Post through troubleshooting we have found out that it was due to OS.
Thanks for your concern , please discard this issue. Issue has been resolved.

Nginx using variables / split_clients is very slow

$
0
0
Hi,

I want to use nginx as reverse proxy for an A/B testing scenario.
The nginx should route to two versions of one backend service. The two versions provides this service via different URL paths.
Example:
* x% of all requests https://edgeservice/myservice should be routed to https://1.2.3.4/myservice,
* the other 100-x% should be routed to https://4.3.2.1/myservice/withAnothePath.
For that I wanted to use the split_client directive that perfectly matches our requirements.

We have a general nginx configuration that reaches a high throughput (at least 2.000 requests / sec) - unless we specify the routing target via nginx variables.

So, when specifying the routing target "hard coded" in the proxy_pass directive (variant 0) or when using the upstream directive (variant 1), the nginx routes very fast (at least 2.000 req/sec).
Once we use split_clients directive to specify the routing target (variant 2) or we set a variable statically (variant 3), the nginx ist very slow and reaches only 20-50 requests / sec. All other config parameters are the same for all variants.

We did some research (nginx config reference, google, this forum...) to find a solution for this problem.
Now that we do not find any approach I wanted to ask the mailing list if you have got any idea?
Is there a solution to increase performance when using split_clients so that we can reach at least 1.000 requests / sec?
Or did we already reach maximum performance for this scenario?

It would be great if we could used split_clients since we are very flexible in defining routing rules and we can route to backend services with different URL paths.

Kind Regards
Lars


nginx 1.10.3 running on Ubunutu trusy
nginx.conf:
...
http {
...

# variant 1
upstream backend1 {
ip_hash;
server 1.2.3.4;
}

# variant 2
split_clients $remote_addr $backend2 {
50% https://1.2.3.4/myservice/;
50% https://4.3.2.1/myservice/withAnotherPath;
}

server {
listen 443 ssl backlog=163840;

# variant 3
set $backend3 https://1.2.3.4/myservice;

location /myservice {
# V0) this is fast
proxy_pass https://1.2.3.4/myservice;

# V1) this is fast
proxy_pass https://backend1;

# V2) this is slow
proxy_pass $backend2;

# V3) this is slow
proxy_pass $backend3;
}
}
}

Re: Nginx using variables / split_clients is very slow

$
0
0
Hello!

On Tue, Feb 28, 2017 at 06:59:00AM -0500, larsg wrote:

> I want to use nginx as reverse proxy for an A/B testing scenario.
> The nginx should route to two versions of one backend service. The two
> versions provides this service via different URL paths.
> Example:
> * x% of all requests https://edgeservice/myservice should be routed to
> https://1.2.3.4/myservice,
> * the other 100-x% should be routed to
> https://4.3.2.1/myservice/withAnothePath.
> For that I wanted to use the split_client directive that perfectly matches
> our requirements.
>
> We have a general nginx configuration that reaches a high throughput (at
> least 2.000 requests / sec) - unless we specify the routing target via nginx
> variables.
>
> So, when specifying the routing target "hard coded" in the proxy_pass
> directive (variant 0) or when using the upstream directive (variant 1), the
> nginx routes very fast (at least 2.000 req/sec).
> Once we use split_clients directive to specify the routing target (variant
> 2) or we set a variable statically (variant 3), the nginx ist very slow and
> reaches only 20-50 requests / sec. All other config parameters are the same
> for all variants.

[...]

> # variant 1
> upstream backend1 {
> ip_hash;
> server 1.2.3.4;
> }
>
> # variant 2
> split_clients $remote_addr $backend2 {
> 50% https://1.2.3.4/myservice/;
> 50% https://4.3.2.1/myservice/withAnotherPath;
> }
>
> server {
> listen 443 ssl backlog=163840;
>
> # variant 3
> set $backend3 https://1.2.3.4/myservice;
>
> location /myservice {
> # V0) this is fast
> proxy_pass https://1.2.3.4/myservice;
>
> # V1) this is fast
> proxy_pass https://backend1;
>
> # V2) this is slow
> proxy_pass $backend2;
>
> # V3) this is slow
> proxy_pass $backend3;

The problem is that your configuration with variables and an IP
address implies run-time parsing of the address to create a
run-time implicit upstream server group nginx will work with.
This group will only be used for a single request. But you use
SSL to connect to upstream servers, and here comes the problem:
SSL sessions are cached within the server group data. As such,
your V2 and V3 configurations does not use SSL session caching,
and hence slow due to a full SSL handshake on each request.

Solution is to use predefined upstream blocks within your
split_clients paths, e.g.:

split_clients $remote_addr $backend {
50% https://backend1;
50% https://backend2;
}

upstream backend1 {
sever 10.0.0.1;
}

upstream backend2 {
sever 10.0.0.2;
}

proxy_pass $backend;

This way nginx will be able to choose an upstream server at
run-time according to split_clients, and will still be able to
cache SSL sessions (or even connections, if configured, see
http://nginx.org/r/keepalive).

Note well that specifing URI in proxy_pass using variables may not
do what you expect. When using variables in proxy_pass, if an URI
part is specified, it means full URI to be used in a request to a
backend, not a replacement for a location prefix matched. See
http://nginx.org/r/proxy_pass for details.

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

Re: set_real_ip_from, real_ip_header directive in ngx_http_realip_module

$
0
0
Hello!

On Tue, Feb 28, 2017 at 09:58:05AM +0900, Nishikubo Minoru wrote:

> Hello,
> I tried to limit an IPv4 Address with ngx_http_limit_req module and
> ngx_realip_module via Akamai would send True-Client-IP headers.
>
> According to the document ngx_http_readip_module(
> http://nginx.org/en/docs/http/ngx_http_realip_module.html),
> we can write set_real_ip_from and real-_ip_header directive in http,
> server, location context.
>
> But, in the above case(ngx_http_limit_req module is defined the key in http
> context), directives on ngx_http_realip_module must be defined before the
> keys(a.k.a replaced IPv4 adress by ngx_http_realip_module) and followed
> limit_req_zone directive in http context.

Not really. There is no such requirement, that is, there is need
to place limit_req_zone and set_real_ip_from on the same level or
even in a particular order.

For example, the following configuration will work perfectly:

limit_req_zone $remote_addr zone=limit:1m rate=1r/m;
limit_req zone=limit;

server {
listen 80;

location / {
set_real_ip_from 127.0.0.1;
real_ip_header X-Real-IP;
}
}

A problem may happen though if you configured the realip module in
a location context, but use the address in different contexts.
For example, the following will limit requests based on the
connection's address, not the one set with realip:

limit_req_zone $remote_addr zone=limit:1m rate=1r/m;
limit_req zone=limit;

server {
listen 80;

location / {
try_files $uri @fallback;
}

location @fallback {
set_real_ip_from 127.0.0.1;
real_ip_header X-Real-IP;
proxy_pass ...
}
}

In the above configuration, limit_req will work at the "location /"
context, and the realip module in "location @fallback" won't be
effective. For more confusion, the $remote_addr variable will be
cached once used by limit_req, and attempts to use it even in the
location @fallback will return the original value, not changed by
the realip module.

Summing up the above, it is certainly possible to use the realip
module with limit_req regardless of levels. They may interact
unexpectedly in complex configurations though, and hence it is
a good idea to avoid using set_real_ip_from / real_ip_header in
location context unless you understand what you are doing.

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

IPv6 upstream problem

$
0
0
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hello!

Currently I have problem with upstream with IPv6. For example I have
an origin with subdomain dual-stack-ipv4-ipv6.xtremenitro.org.

dual-stack-ipv4-ipv6.xtremenitro.org IN A 192.168.1.1
dual-stack-ipv4-ipv6.xtremenitro.org IN AAAA 2001:xx:xx::1;

My configuration are like this :
$ nginx -V
nginx version: nginx/1.11.10
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with LibreSSL 2.4.5
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx
- --modules-path=/usr/lib64/nginx/modules
- --conf-path=/etc/nginx/nginx.conf
- --error-log-path=/var/log/nginx/error.log
- --http-log-path=/var/log/nginx/access.log
- --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock
- --http-client-body-temp-path=/var/cache/nginx/client_temp
- --http-proxy-temp-path=/var/cache/nginx/proxy_temp
- --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
- --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
- --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx
- --group=nginx --with-http_ssl_module --with-openssl=libressl-2.4.5
- --with-http_realip_module --with-http_addition_module
- --with-http_sub_module --with-http_gunzip_module
- --with-http_gzip_static_module --with-http_random_index_module
- --with-http_stub_status_module --with-http_auth_request_module
- --with-http_image_filter_module=dynamic
- --with-http_geoip_module=dynamic --with-http_perl_module=dynamic
- --with-http_xslt_module=dynamic --add-dynamic-module=ngx_cache_purge
- --add-dynamic-module=nginx-module-vts
- --add-dynamic-module=headers-more-nginx-module
- --add-dynamic-module=ngx_small_light --add-dynamic-module=ngx_brotli
- --add-dynamic-module=nginx_upstream_check_module --with-threads
- --with-stream=dynamic --with-stream_ssl_module
- --with-http_slice_module --with-mail=dynamic --with-mail_ssl_module
- --with-file-aio --with-ipv6 --with-http_v2_module --with-cc-opt='-g
- -Ofast -march=native -ffast-math -fstack-protector-strong -Wformat
- -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2'


...
resolver 103.52.3.72 ipv6=off;

upstream cf {
server dual-stack-ipv4-ipv6.xtremenitro.org;
}

.... snip ...

location ~ \.(jpe?g|gif|png|JPE?G|GIF|PNG)$ {
proxy_pass http://cf;
proxy_cache_background_update on;
proxy_cache_use_stale error timeout updating http_500
http_502 http_503 http_504;
proxy_cache_valid 200 302 301 60m;
proxy_cache images;
proxy_cache_valid any 3s;
proxy_cache_lock on;
proxy_cache_lock_timeout 60s;
proxy_cache_min_uses 1;
proxy_ignore_headers Cache-Control Expires;
proxy_hide_header X-Cache;
proxy_hide_header Via;
proxy_hide_header ETag;
}

I see on error log, all error was came from IPv6 upstream.

2017/02/28 22:13:15 [error] 24079#24079: *429979 upstream timed out
(110: Connection timed out) while connecting to upstream, client:
114.120.233.8, server: dual-stack-ipv4-ipv6.xtremenitro.org, request:
"GET /2015-09/thumbnail_360/wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg
HTTP/2.0", subrequest:
"/2015-09/thumbnail_360/wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg",
upstream:
"http://[2600:9000:2031:4000:6:24ba:3100:93a1]:80/2015-09/thumbnail_360/
wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg?of=webp&q=50",
host: "dual-stack-ipv4-ipv6.xtremenitro.org", referrer: "[REMOVED]"
2017/02/28 22:13:20 [error] 24080#24080: *432226 upstream timed out
(110: Connection timed out) while connecting to upstream, client:
124.153.33.23, server: dual-stack-ipv4-ipv6.xtremenitro.org, request:
"GET /2016-02/thumbnail_360/wd/df4f88d6a5d62427c11e746e187ba527.jpg
HTTP/1.1", subrequest:
"/2016-02/thumbnail_360/wd/df4f88d6a5d62427c11e746e187ba527.jpg",
upstream:
"http://[2600:9000:2031:7e00:6:24ba:3100:93a1]:80/2016-02/thumbnail_360/
wd/df4f88d6a5d62427c11e746e187ba527.jpg?of=webp&q=50",
host: "dual-stack-ipv4-ipv6.xtremenitro.org", referrer: "[REMOVED]"

Any hints, clue or help are very appreciated.
Thanks in advance
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQI4BAEBCAAiBQJYtZ3JGxxkZXdhbmdnYWJhQHh0cmVtZW5pdHJvLm9yZwAKCRDl
f9IgoCjNcFiXD/46SeZToPFxfwaG2SwFtbMCsa3e2aelQOdjl36o893zgN7EkgkU
NIiLBTuydSke0I2tF6uof2eCpJdKaxP1R+iWPa3FE1rfn8s3gE32CnJZetBzaPn2
/6j1S5s5ZfT8n+91URAvAzEvBzhWfqErJqWH+Q8JYvrW57eEn/6DoIqcyyqw287m
ZbSovx+bkTj3q+hClxURyU+oHq8g1TaiGimp8eBWmdyciTn+vk8L5qUZ8rgFniBS
75zVoZvim3yO7qpnCi98gFv1N+ghlEnqRtO/xNoC+I7cCbp93OoWfQi8z6T9Ljyu
pkg7ptNZ8slIHhcsjxf6V3wW6Uuih0q/BFdc8WVmNzkL/tfW6cwBDzz2kymcaOBl
hB+KRMsS5yTj4uVpnabzqDMRANUw/mvaM+t+4XWcvXWVhQY1pHT+pynD1kVzXnug
EGszUcA71ZNMPqH9fGLrN7igaBRRt1GMn7/sqNQKmY54GwjSJAziE0edpapBrP7I
aWMQaLdc7DBudlR4rMNaXt9bGh/2oQm1T4/xImK8sp9SHBFKyZBkMZq+UnGdPlGZ
UyU/XOJrDca//ipsI2g3G6LUBpUKJtoE6bMsTRhakMaU8K3T0s1sgB1oBYsNQGyb
YpLDfnZMxXk/Jn2ttXG22E1b8MtQsDdn946hsRrGddIWg+4bucgzEbAYLA==
=Cs9Q
-----END PGP SIGNATURE-----
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

Re: IPv6 upstream problem

$
0
0
Hello!

On Tue, Feb 28, 2017 at 10:57:01PM +0700, Dewangga Bachrul Alam wrote:

> Currently I have problem with upstream with IPv6. For example I have
> an origin with subdomain dual-stack-ipv4-ipv6.xtremenitro.org.
>
> dual-stack-ipv4-ipv6.xtremenitro.org IN A 192.168.1.1
> dual-stack-ipv4-ipv6.xtremenitro.org IN AAAA 2001:xx:xx::1;

[...]

> resolver 103.52.3.72 ipv6=off;
>
> upstream cf {
> server dual-stack-ipv4-ipv6.xtremenitro.org;

[...]

> I see on error log, all error was came from IPv6 upstream.
>
> 2017/02/28 22:13:15 [error] 24079#24079: *429979 upstream timed out
> (110: Connection timed out) while connecting to upstream, client:
> 114.120.233.8, server: dual-stack-ipv4-ipv6.xtremenitro.org, request:
> "GET /2015-09/thumbnail_360/wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg
> HTTP/2.0", subrequest:
> "/2015-09/thumbnail_360/wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg",
> upstream:
> "http://[2600:9000:2031:4000:6:24ba:3100:93a1]:80/2015-09/thumbnail_360/
> wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg?of=webp&q=50",
> host: "dual-stack-ipv4-ipv6.xtremenitro.org", referrer: "[REMOVED]"

It looks like you assume that "resolver ... ipv6=off" is expected
to prevent nginx from using IPv6 addresses of all names written in
the configuration. This is not how it works though.

The "resolver" directive is only used for dynamic resolution of
names not known during configuration parsing. Most notably, it is
used to resolve names in proxy_pass with variables.

The name in the "server dual-stack-ipv4-ipv6.xtremenitro.org;" is
known while configuration parsing, and nginx will simply use the
getaddrinfo() function to resolve it. You have to tune your OS
name resolution settings if you want it to return IPv4 addresses
only.

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

Re: IPv6 upstream problem

$
0
0
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hello!

On 03/01/2017 12:15 AM, Maxim Dounin wrote:
> Hello!
>
> On Tue, Feb 28, 2017 at 10:57:01PM +0700, Dewangga Bachrul Alam
> wrote:
>
>> Currently I have problem with upstream with IPv6. For example I
>> have an origin with subdomain
>> dual-stack-ipv4-ipv6.xtremenitro.org.
>>
>> dual-stack-ipv4-ipv6.xtremenitro.org IN A 192.168.1.1
>> dual-stack-ipv4-ipv6.xtremenitro.org IN AAAA 2001:xx:xx::1;
>
> [...]
>
>> resolver 103.52.3.72 ipv6=off;
>>
>> upstream cf { server dual-stack-ipv4-ipv6.xtremenitro.org;
>
> [...]
>
>> I see on error log, all error was came from IPv6 upstream.
>>
>> 2017/02/28 22:13:15 [error] 24079#24079: *429979 upstream timed
>> out (110: Connection timed out) while connecting to upstream,
>> client: 114.120.233.8, server:
>> dual-stack-ipv4-ipv6.xtremenitro.org, request: "GET
>> /2015-09/thumbnail_360/wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg
>> HTTP/2.0", subrequest:
>> "/2015-09/thumbnail_360/wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg",
>>
>>
upstream:
>> "http://[2600:9000:2031:4000:6:24ba:3100:93a1]:80/2015-09/thumbnail_3
60/
>>
>>
wd/d7d63419f8ac6b6981cec72c8a6644ea.jpg?of=webp&q=50",
>> host: "dual-stack-ipv4-ipv6.xtremenitro.org", referrer:
>> "[REMOVED]"
>
[..]

> It looks like you assume that "resolver ... ipv6=off" is expected
> to prevent nginx from using IPv6 addresses of all names written in
> the configuration. This is not how it works though.

Yes

>
> The "resolver" directive is only used for dynamic resolution of
> names not known during configuration parsing. Most notably, it is
> used to resolve names in proxy_pass with variables.
>
[..]
> The name in the "server dual-stack-ipv4-ipv6.xtremenitro.org;" is
> known while configuration parsing, and nginx will simply use the
> getaddrinfo() function to resolve it. You have to tune your OS
> name resolution settings if you want it to return IPv4 addresses
> only.
>

Ah! I was thought nginx can handle whether the upstream using fqdn
could be forced only IPv4 and/or IPv6.

Thanks for the hints, Maxim.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQI4BAEBCAAiBQJYtbJNGxxkZXdhbmdnYWJhQHh0cmVtZW5pdHJvLm9yZwAKCRDl
f9IgoCjNcG2AD/wKBQ27TVpnShX3/FFzNT0BH1EzvbthVc05KDsc8wRI8LnA+zLG
nrtvnoCGW3mL/9z85uU78soYpPzewlIo12k75NQnaxkk99lb6wq2UrQI+X6ZEZuE
dT6y/ILKnY/VpawKj/6V14WKmv/1MYTY08/yv9RpcK4VvabGBwF6E1b6hiiM+tUn
9BXBYomBJTI6B6HCbMPQBI/5haPrWHg952w0BqbcrinrXJ3670pZfDxt1Q3zCyTn
KvTw/sVnMGHpf5yE8zh+CkgQWiyTBegC7BdLH6uPEjJQ4x/6Zt1P3K8LzlBjwwd/
Jb0FdlK+CgYilZ1n8JSi56gwxaDgUl+Cxf0PCliMCPr1Gn7JOxumvJes6VDBSTZu
J2wNVLJC+JOnWYVKgtCMc4DHB8s8M7JXqHhsL0tET7Q+G/cl1Fg76aSVhutu5mKu
v9tBFyyKYu6gLtODw3ust7K3Jt0NS/sldXN1ZVXfZEdmeBCT4TRB22Q0CO0a8/Uv
5IdjXE7mx7PDEzzryZuIztEzKhUl7KD3HijRZbKZzS3UUOAIHalhp2MnGrHqjLdA
OKXv8coW9b0hY1POe34eVKgfK0cz2y3QlHZzIhARZExIzRsmPCBB6Pi2U+TzWYcV
qQNEFzIjZGbOKYtzw6ummf5uFBPTUIyQqPgB8wUI7fANXLcG9pHs+MoUiw==
=Bw12
-----END PGP SIGNATURE-----
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

Re: Nginx using variables / split_clients is very slow

$
0
0
Dear Maxim,

thank you very much.
This solved my problem! Great!

Kind Regards
Lars

Add missing static specifiers

$
0
0
Hi all,

Wrote a small script to find missing 'static's in my module -
https://github.com/kaltura/nginx-vod-module/blob/master/test/test_static.py

I executed it on nginx core and found a few of those too, see attached patch.
The logic for finding these was -

1. An exported symbol (found by running readelf on all object files)

2. Appears only in one source file (I could have checked the object imports instead, but anyway,
that's how it works...)

3. Not mentioned in any header file (simple 'find whole words' search)

4. Does not end with '_module'

Btw, the script also complained about ngx_noaccepting and ngx_restart, I did not change those since
all other flags there are exported.

Thanks!

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

Re: Add missing static specifiers

$
0
0
Hello!

On Tue, Feb 28, 2017 at 07:20:49PM +0000, Eran Kornblau wrote:

> Hi all,
>
> Wrote a small script to find missing 'static's in my module -
> https://github.com/kaltura/nginx-vod-module/blob/master/test/test_static.py
>
> I executed it on nginx core and found a few of those too, see attached patch.
> The logic for finding these was -
>
> 1. An exported symbol (found by running readelf on all object files)
>
> 2. Appears only in one source file (I could have checked the object imports instead, but anyway,
> that's how it works...)
>
> 3. Not mentioned in any header file (simple 'find whole words' search)
>
> 4. Does not end with '_module'
>
> Btw, the script also complained about ngx_noaccepting and ngx_restart, I did not change those since
> all other flags there are exported.

Thank you, looks interesting.
Quick review below.

> # HG changeset patch
> # User Eran Kornblau <erankor@gmail.com>
> # Date 1488300547 18000
> # Tue Feb 28 11:49:07 2017 -0500
> # Node ID 4b4b8f5413a4a1679d6ad0aa444e29e3f55b6b2a
> # Parent 8b7fd958c59f8280d167fe7dd93f1942bfed5876
> add missing static specifiers

Style nitpicking:

Added missing static specifiers.


>
> diff -r 8b7fd958c59f -r 4b4b8f5413a4 src/core/ngx_resolver.c
> --- a/src/core/ngx_resolver.c Mon Feb 27 22:36:15 2017 +0300
> +++ b/src/core/ngx_resolver.c Tue Feb 28 11:49:07 2017 -0500
> @@ -56,7 +56,7 @@
> ((u_char *) (n) - offsetof(ngx_resolver_node_t, node))
>
>
> -ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec);
> +static ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec);
> ngx_int_t ngx_tcp_connect(ngx_resolver_connection_t *rec);
>
>

I'm curious why ngx_udp_connect() was catched, but exactly
identical ngx_tcp_connect() wasn't.

> @@ -4379,7 +4379,7 @@
> }
>
>
> -ngx_int_t
> +static ngx_int_t
> ngx_udp_connect(ngx_resolver_connection_t *rec)
> {
> int rc;
> diff -r 8b7fd958c59f -r 4b4b8f5413a4 src/event/modules/ngx_epoll_module.c
> --- a/src/event/modules/ngx_epoll_module.c Mon Feb 27 22:36:15 2017 +0300
> +++ b/src/event/modules/ngx_epoll_module.c Tue Feb 28 11:49:07 2017 -0500
> @@ -176,7 +176,7 @@
> };
>
>
> -ngx_event_module_t ngx_epoll_module_ctx = {
> +static ngx_event_module_t ngx_epoll_module_ctx = {
> &epoll_name,
> ngx_epoll_create_conf, /* create configuration */
> ngx_epoll_init_conf, /* init configuration */
> diff -r 8b7fd958c59f -r 4b4b8f5413a4 src/event/ngx_event.c
> --- a/src/event/ngx_event.c Mon Feb 27 22:36:15 2017 +0300
> +++ b/src/event/ngx_event.c Tue Feb 28 11:49:07 2017 -0500
> @@ -165,7 +165,7 @@
> };
>
>
> -ngx_event_module_t ngx_event_core_module_ctx = {
> +static ngx_event_module_t ngx_event_core_module_ctx = {
> &event_core_name,
> ngx_event_core_create_conf, /* create configuration */
> ngx_event_core_init_conf, /* init configuration */

Note that all event modules currently use non-static contexts.
Obviously your script can't catch symbols in modules you don't
have compiled in, but a simple grep will allow to properly extend
this to other modules.

> diff -r 8b7fd958c59f -r 4b4b8f5413a4 src/http/modules/ngx_http_charset_filter_module.c
> --- a/src/http/modules/ngx_http_charset_filter_module.c Mon Feb 27 22:36:15 2017 +0300
> +++ b/src/http/modules/ngx_http_charset_filter_module.c Tue Feb 28 11:49:07 2017 -0500
> @@ -123,7 +123,7 @@
> static ngx_int_t ngx_http_charset_postconfiguration(ngx_conf_t *cf);
>
>
> -ngx_str_t ngx_http_charset_default_types[] = {
> +static ngx_str_t ngx_http_charset_default_types[] = {
> ngx_string("text/html"),
> ngx_string("text/xml"),
> ngx_string("text/plain"),

The ngx_http_xslt_default_types variable seems to be exactly
identical.

> diff -r 8b7fd958c59f -r 4b4b8f5413a4 src/http/modules/ngx_http_static_module.c
> --- a/src/http/modules/ngx_http_static_module.c Mon Feb 27 22:36:15 2017 +0300
> +++ b/src/http/modules/ngx_http_static_module.c Tue Feb 28 11:49:07 2017 -0500
> @@ -14,7 +14,7 @@
> static ngx_int_t ngx_http_static_init(ngx_conf_t *cf);
>
>
> -ngx_http_module_t ngx_http_static_module_ctx = {
> +static ngx_http_module_t ngx_http_static_module_ctx = {
> NULL, /* preconfiguration */
> ngx_http_static_init, /* postconfiguration */
>

As per

$ grep -rh ngx_http_module_t src/ | grep -v '^static'

there is also ngx_http_gzip_static_module_ctx which is also not
static.

> diff -r 8b7fd958c59f -r 4b4b8f5413a4 src/http/ngx_http_upstream.c
> --- a/src/http/ngx_http_upstream.c Mon Feb 27 22:36:15 2017 +0300
> +++ b/src/http/ngx_http_upstream.c Tue Feb 28 11:49:07 2017 -0500
> @@ -188,7 +188,7 @@
> #endif
>
>
> -ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
> +static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
>
> { ngx_string("Status"),
> ngx_http_upstream_process_header_line,
> diff -r 8b7fd958c59f -r 4b4b8f5413a4 src/os/unix/ngx_linux_init.c
> --- a/src/os/unix/ngx_linux_init.c Mon Feb 27 22:36:15 2017 +0300
> +++ b/src/os/unix/ngx_linux_init.c Tue Feb 28 11:49:07 2017 -0500
> @@ -9,8 +9,8 @@
> #include <ngx_core.h>
>
>
> -u_char ngx_linux_kern_ostype[50];
> -u_char ngx_linux_kern_osrelease[50];
> +static u_char ngx_linux_kern_ostype[50];
> +static u_char ngx_linux_kern_osrelease[50];

There are various OS-specific variables for various other
platforms as well. It would be a good idea to either review them
all, or left them as is.

[...]

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

[PATCH 1 of 3] HTTP: add support for "429 Too Many Requests" response (RFC6585)

$
0
0
# HG changeset patch
# User Piotr Sikora <piotrsikora@google.com>
# Date 1488324535 28800
# Tue Feb 28 15:28:55 2017 -0800
# Node ID 9a63d6e990d230db0ec6b03250265447f648526e
# Parent 8b7fd958c59f8280d167fe7dd93f1942bfed5876
HTTP: add support for "429 Too Many Requests" response (RFC6585).

This change adds reason phrase in status line and pretty response body
when "429" status code is used in "return", "limit_conn_status" and/or
"limit_req_status" directives.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>

diff -r 8b7fd958c59f -r 9a63d6e990d2 src/http/ngx_http_header_filter_module.c
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -101,12 +101,16 @@ static ngx_str_t ngx_http_status_lines[]
ngx_null_string, /* "419 unused" */
ngx_null_string, /* "420 unused" */
ngx_string("421 Misdirected Request"),
+ ngx_null_string, /* "422 Unprocessable Entity" */
+ ngx_null_string, /* "423 Locked" */
+ ngx_null_string, /* "424 Failed Dependency" */
+ ngx_null_string, /* "425 unused" */
+ ngx_null_string, /* "426 Upgrade Required" */
+ ngx_null_string, /* "427 unused" */
+ ngx_null_string, /* "428 Precondition Required" */
+ ngx_string("429 Too Many Requests"),

- /* ngx_null_string, */ /* "422 Unprocessable Entity" */
- /* ngx_null_string, */ /* "423 Locked" */
- /* ngx_null_string, */ /* "424 Failed Dependency" */
-
-#define NGX_HTTP_LAST_4XX 422
+#define NGX_HTTP_LAST_4XX 430
#define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)

ngx_string("500 Internal Server Error"),
diff -r 8b7fd958c59f -r 9a63d6e990d2 src/http/ngx_http_request.h
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -98,6 +98,7 @@
#define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE 415
#define NGX_HTTP_RANGE_NOT_SATISFIABLE 416
#define NGX_HTTP_MISDIRECTED_REQUEST 421
+#define NGX_HTTP_TOO_MANY_REQUESTS 429


/* Our own HTTP codes */
diff -r 8b7fd958c59f -r 9a63d6e990d2 src/http/ngx_http_special_response.c
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -225,6 +225,14 @@ static char ngx_http_error_421_page[] =
;


+static char ngx_http_error_429_page[] =
+"<html>" CRLF
+"<head><title>429 Too Many Requests</title></head>" CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>429 Too Many Requests</h1></center>" CRLF
+;
+
+
static char ngx_http_error_494_page[] =
"<html>" CRLF
"<head><title>400 Request Header Or Cookie Too Large</title></head>"
@@ -354,8 +362,16 @@ static ngx_str_t ngx_http_error_pages[]
ngx_null_string, /* 419 */
ngx_null_string, /* 420 */
ngx_string(ngx_http_error_421_page),
+ ngx_null_string, /* 422 */
+ ngx_null_string, /* 423 */
+ ngx_null_string, /* 424 */
+ ngx_null_string, /* 425 */
+ ngx_null_string, /* 426 */
+ ngx_null_string, /* 427 */
+ ngx_null_string, /* 428 */
+ ngx_string(ngx_http_error_429_page),

-#define NGX_HTTP_LAST_4XX 422
+#define NGX_HTTP_LAST_4XX 430
#define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)

ngx_string(ngx_http_error_494_page), /* 494, request header too large */
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

[PATCH 2 of 3] Upstream: allow recovery from "429 Too Many Requests" response

$
0
0
# HG changeset patch
# User Piotr Sikora <piotrsikora@google.com>
# Date 1488324535 28800
# Tue Feb 28 15:28:55 2017 -0800
# Node ID e21f12a958010e1f3e5cdc1640859e335e032ca5
# Parent 9a63d6e990d230db0ec6b03250265447f648526e
Upstream: allow recovery from "429 Too Many Requests" response.

This change adds "http_429" parameter to "proxy_next_upstream" for
retrying rate-limited requests, and to "proxy_cache_use_stale" for
serving stale cached responses after being rate-limited.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>

diff -r 9a63d6e990d2 -r e21f12a95801 src/http/modules/ngx_http_fastcgi_module.c
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -211,6 +211,7 @@ static ngx_conf_bitmask_t ngx_http_fast
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+ { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
{ ngx_null_string, 0 }
diff -r 9a63d6e990d2 -r e21f12a95801 src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -220,6 +220,7 @@ static ngx_conf_bitmask_t ngx_http_prox
{ ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+ { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
{ ngx_null_string, 0 }
diff -r 9a63d6e990d2 -r e21f12a95801 src/http/modules/ngx_http_scgi_module.c
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -82,6 +82,7 @@ static ngx_conf_bitmask_t ngx_http_scgi_
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+ { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
{ ngx_null_string, 0 }
diff -r 9a63d6e990d2 -r e21f12a95801 src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -114,6 +114,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+ { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
{ ngx_null_string, 0 }
diff -r 9a63d6e990d2 -r e21f12a95801 src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -436,6 +436,7 @@ static ngx_http_upstream_next_t ngx_htt
{ 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
{ 403, NGX_HTTP_UPSTREAM_FT_HTTP_403 },
{ 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+ { 429, NGX_HTTP_UPSTREAM_FT_HTTP_429 },
{ 0, 0 }
};

@@ -4115,7 +4116,8 @@ ngx_http_upstream_next(ngx_http_request_
if (u->peer.sockaddr) {

if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_403
- || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404)
+ || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404
+ || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_429)
{
state = NGX_PEER_NEXT;

@@ -4155,6 +4157,10 @@ ngx_http_upstream_next(ngx_http_request_
status = NGX_HTTP_NOT_FOUND;
break;

+ case NGX_HTTP_UPSTREAM_FT_HTTP_429:
+ status = NGX_HTTP_TOO_MANY_REQUESTS;
+ break;
+
/*
* NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
* never reach here
diff -r 9a63d6e990d2 -r e21f12a95801 src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -26,10 +26,11 @@
#define NGX_HTTP_UPSTREAM_FT_HTTP_504 0x00000080
#define NGX_HTTP_UPSTREAM_FT_HTTP_403 0x00000100
#define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000200
-#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000400
-#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000800
-#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00001000
-#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00002000
+#define NGX_HTTP_UPSTREAM_FT_HTTP_429 0x00000400
+#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000800
+#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00001000
+#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00002000
+#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00004000
#define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000
#define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000

@@ -38,7 +39,8 @@
|NGX_HTTP_UPSTREAM_FT_HTTP_503 \
|NGX_HTTP_UPSTREAM_FT_HTTP_504 \
|NGX_HTTP_UPSTREAM_FT_HTTP_403 \
- |NGX_HTTP_UPSTREAM_FT_HTTP_404)
+ |NGX_HTTP_UPSTREAM_FT_HTTP_404 \
+ |NGX_HTTP_UPSTREAM_FT_HTTP_429)

#define NGX_HTTP_UPSTREAM_INVALID_HEADER 40

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

[PATCH 3 of 3] Limit req: change default response code when rate-limiting

$
0
0
# HG changeset patch
# User Piotr Sikora <piotrsikora@google.com>
# Date 1488324535 28800
# Tue Feb 28 15:28:55 2017 -0800
# Node ID c9d43c652ac776068e78f695dde00606eed184f8
# Parent e21f12a958010e1f3e5cdc1640859e335e032ca5
Limit req: change default response code when rate-limiting.

Previously, "503 Service Unavailable" response code was used, but
the new "429 Too Many Requests" response code is more appropriate.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>

diff -r e21f12a95801 -r c9d43c652ac7 src/http/modules/ngx_http_limit_req_module.c
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -712,7 +712,7 @@ ngx_http_limit_req_merge_conf(ngx_conf_t
NGX_LOG_INFO : conf->limit_log_level + 1;

ngx_conf_merge_uint_value(conf->status_code, prev->status_code,
- NGX_HTTP_SERVICE_UNAVAILABLE);
+ NGX_HTTP_TOO_MANY_REQUESTS);

return NGX_CONF_OK;
}
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: set_real_ip_from, real_ip_header directive in ngx_http_realip_module

$
0
0
Hello, Maxim

I understand your explanation and thanks for reply.

I tried to replace $binary_remote_addr (not $remote_addr for performance
reason) with True-Client-IP header which is Akamai CDN Server will send,
via ngx_http_limit_req_module and use as a shared memory zone key.


On Tue, Feb 28, 2017 at 10:40 PM, Maxim Dounin <mdounin@mdounin.ru> wrote:

> Hello!
>
> On Tue, Feb 28, 2017 at 09:58:05AM +0900, Nishikubo Minoru wrote:
>
> > Hello,
> > I tried to limit an IPv4 Address with ngx_http_limit_req module and
> > ngx_realip_module via Akamai would send True-Client-IP headers.
> >
> > According to the document ngx_http_readip_module(
> > http://nginx.org/en/docs/http/ngx_http_realip_module.html),
> > we can write set_real_ip_from and real-_ip_header directive in http,
> > server, location context.
> >
> > But, in the above case(ngx_http_limit_req module is defined the key in
> http
> > context), directives on ngx_http_realip_module must be defined before the
> > keys(a.k.a replaced IPv4 adress by ngx_http_realip_module) and followed
> > limit_req_zone directive in http context.
>
> Not really. There is no such requirement, that is, there is need
> to place limit_req_zone and set_real_ip_from on the same level or
> even in a particular order.
>
> For example, the following configuration will work perfectly:
>
> limit_req_zone $remote_addr zone=limit:1m rate=1r/m;
> limit_req zone=limit;
>
> server {
> listen 80;
>
> location / {
> set_real_ip_from 127.0.0.1;
> real_ip_header X-Real-IP;
> }
> }
>
> A problem may happen though if you configured the realip module in
> a location context, but use the address in different contexts.
> For example, the following will limit requests based on the
> connection's address, not the one set with realip:
>
> limit_req_zone $remote_addr zone=limit:1m rate=1r/m;
> limit_req zone=limit;
>
> server {
> listen 80;
>
> location / {
> try_files $uri @fallback;
> }
>
> location @fallback {
> set_real_ip_from 127.0.0.1;
> real_ip_header X-Real-IP;
> proxy_pass ...
> }
> }
>
> In the above configuration, limit_req will work at the "location /"
> context, and the realip module in "location @fallback" won't be
> effective. For more confusion, the $remote_addr variable will be
> cached once used by limit_req, and attempts to use it even in the
> location @fallback will return the original value, not changed by
> the realip module.
>
> Summing up the above, it is certainly possible to use the realip
> module with limit_req regardless of levels. They may interact
> unexpectedly in complex configurations though, and hence it is
> a good idea to avoid using set_real_ip_from / real_ip_header in
> location context unless you understand what you are doing.
>
> --
> Maxim Dounin
> http://nginx.org/
> _______________________________________________
> nginx mailing list
> nginx@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx
>
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

Re: Nginx with a ICAP-like front-end

$
0
0
Rajeev, you meant asking the validator or client to set X-Accel-Redirect?
Could you elaborate here? Thanks,

On Mon, Feb 27, 2017 at 9:14 AM, Rajeev J Sebastian <
rajeev.sebastian@gmail.com> wrote:

> Adler, maybe you should try X-Accel-Redirect to avoid this conversion of
> POST to GET?
>
> On Mon, Feb 27, 2017 at 10:41 PM, Rajeev J Sebastian <
> rajeev.sebastian@gmail.com> wrote:
>
>> From the docs it seems that this will work for all requests EXCEPT that,
>> the @success fallback request will always be GET.
>>
>> On Mon, Feb 27, 2017 at 10:30 PM, Alder Netw <aldernetwork@gmail.com>
>> wrote:
>>
>>> Thanks Rajeev for the recipe, I was looking into using subrequest but
>>> found subrequest
>>> only works for filter module. This looks much simpler! The only concern
>>> is error_page
>>> is only for GET/HEAD not for POST?
>>>
>>>
>>>
>>> On Sun, Feb 26, 2017 at 11:48 PM, Rajeev J Sebastian <
>>> rajeev.sebastian@gmail.com> wrote:
>>>
>>>> Not sure if this is foolproof ... but maybe you can use the error_page
>>>> fallback by responding with a special status_code.
>>>>
>>>> http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
>>>>
>>>> location / {
>>>>
>>>> proxy_pass http://validator;
>>>> error_page 510 = @success;
>>>> }
>>>>
>>>> location @success {
>>>> proxy_pass http://realbackend;
>>>> }
>>>>
>>>>
>>>> On Mon, Feb 27, 2017 at 3:41 AM, Alder Netw <aldernetwork@gmail.com>
>>>> wrote:
>>>>
>>>>> Or is there any existing module that can be adapted to achieve this?
>>>>> Appreciate if someone can shed some light. Thx,
>>>>> - Alder
>>>>>
>>>>> On Sat, Feb 25, 2017 at 9:24 PM, Alder Netw <aldernetwork@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> Hi I want to add an ICAP-like front-end validation server V with
>>>>>> nginx.
>>>>>> The user scenario is like this:
>>>>>>
>>>>>> The client will usually access the real app server R via nginx, but
>>>>>> with
>>>>>> a validation server V, the client request will first pass to V, V
>>>>>> will dp certain
>>>>>> validation and upon sucess the request will be forwarded to R and R
>>>>>> will
>>>>>> return directly to clients; Upon failure, the request will be denied.
>>>>>>
>>>>>> Is there any easy nginx config which can achieve this? Thanks,
>>>>>>
>>>>>> - Alder
>>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> nginx mailing list
>>>>> nginx@nginx.org
>>>>> http://mailman.nginx.org/mailman/listinfo/nginx
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> nginx mailing list
>>>> nginx@nginx.org
>>>> http://mailman.nginx.org/mailman/listinfo/nginx
>>>>
>>>
>>>
>>> _______________________________________________
>>> nginx mailing list
>>> nginx@nginx.org
>>> http://mailman.nginx.org/mailman/listinfo/nginx
>>>
>>
>>
>
> _______________________________________________
> nginx mailing list
> nginx@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx
>
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Viewing all 53287 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>