Mercurial > hg > nginx
diff src/http/ngx_http_core_module.c @ 5084:f7fe817c92a2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Wed, 27 Feb 2013 13:29:50 +0000 |
parents | 44fcb9677c3f |
children | 1b204b8ea9a3 |
line wrap: on
line diff
--- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -76,6 +76,9 @@ static ngx_uint_t ngx_http_gzip_quantity static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); #endif +static ngx_int_t ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, + ngx_addr_t *addr, u_char *xff, size_t xfflen, ngx_array_t *proxies, + int recursive); #if (NGX_HAVE_OPENAT) static char *ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -2747,10 +2750,58 @@ ngx_http_set_disable_symlinks(ngx_http_r ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, + ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies, + int recursive) +{ + ngx_int_t rc; + ngx_uint_t i, found; + ngx_table_elt_t **h; + + if (headers == NULL) { + return ngx_http_get_forwarded_addr_internal(r, addr, value->data, + value->len, proxies, + recursive); + } + + i = headers->nelts; + h = headers->elts; + + rc = NGX_DECLINED; + + found = 0; + + while (i-- > 0) { + rc = ngx_http_get_forwarded_addr_internal(r, addr, h[i]->value.data, + h[i]->value.len, proxies, + recursive); + + if (!recursive) { + break; + } + + if (rc == NGX_DECLINED && found) { + rc = NGX_DONE; + break; + } + + if (rc != NGX_OK) { + break; + } + + found = 1; + } + + return rc; +} + + +static ngx_int_t +ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr, u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive) { u_char *p; in_addr_t inaddr; + ngx_int_t rc; ngx_addr_t paddr; ngx_cidr_t *cidr; ngx_uint_t family, i; @@ -2842,8 +2893,15 @@ ngx_http_get_forwarded_addr(ngx_http_req *addr = paddr; if (recursive && p > xff) { - (void) ngx_http_get_forwarded_addr(r, addr, xff, p - 1 - xff, - proxies, 1); + rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff, + proxies, 1); + + if (rc == NGX_DECLINED) { + return NGX_DONE; + } + + /* rc == NGX_OK || rc == NGX_DONE */ + return rc; } return NGX_OK;