summaryrefslogtreecommitdiffhomepage
path: root/src/http/modules
diff options
context:
space:
mode:
authorRuslan Ermilov <ru@nginx.com>2013-02-27 13:29:50 +0000
committerRuslan Ermilov <ru@nginx.com>2013-02-27 13:29:50 +0000
commit67a68720b7f08542c891d7b9ef08f07e3543b0e4 (patch)
treeb61423ee7b49a7280f87d66606c96785681d71ad /src/http/modules
parent40ea120b34342a3aa80f27378c7f05360b2da7a0 (diff)
downloadnginx-67a68720b7f08542c891d7b9ef08f07e3543b0e4.tar.gz
nginx-67a68720b7f08542c891d7b9ef08f07e3543b0e4.tar.bz2
Correctly handle multiple X-Forwarded-For headers (ticket #106).
Diffstat (limited to 'src/http/modules')
-rw-r--r--src/http/modules/ngx_http_geo_module.c11
-rw-r--r--src/http/modules/ngx_http_geoip_module.c22
-rw-r--r--src/http/modules/ngx_http_proxy_module.c30
-rw-r--r--src/http/modules/ngx_http_realip_module.c25
4 files changed, 49 insertions, 39 deletions
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c
index a927ab798..725baa211 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -314,18 +314,17 @@ static ngx_int_t
ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
ngx_addr_t *addr)
{
- ngx_table_elt_t *xfwd;
+ ngx_array_t *xfwd;
if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) {
return NGX_ERROR;
}
- xfwd = r->headers_in.x_forwarded_for;
+ xfwd = &r->headers_in.x_forwarded_for;
- if (xfwd != NULL && ctx->proxies != NULL) {
- (void) ngx_http_get_forwarded_addr(r, addr, xfwd->value.data,
- xfwd->value.len, ctx->proxies,
- ctx->proxy_recursive);
+ if (xfwd->nelts > 0 && ctx->proxies != NULL) {
+ (void) ngx_http_get_forwarded_addr(r, addr, xfwd, NULL,
+ ctx->proxies, ctx->proxy_recursive);
}
return NGX_OK;
diff --git a/src/http/modules/ngx_http_geoip_module.c b/src/http/modules/ngx_http_geoip_module.c
index 364106519..576fc5f3c 100644
--- a/src/http/modules/ngx_http_geoip_module.c
+++ b/src/http/modules/ngx_http_geoip_module.c
@@ -240,19 +240,18 @@ static u_long
ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
{
ngx_addr_t addr;
- ngx_table_elt_t *xfwd;
+ ngx_array_t *xfwd;
struct sockaddr_in *sin;
addr.sockaddr = r->connection->sockaddr;
addr.socklen = r->connection->socklen;
/* addr.name = r->connection->addr_text; */
- xfwd = r->headers_in.x_forwarded_for;
+ xfwd = &r->headers_in.x_forwarded_for;
- if (xfwd != NULL && gcf->proxies != NULL) {
- (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
- xfwd->value.len, gcf->proxies,
- gcf->proxy_recursive);
+ if (xfwd->nelts > 0 && gcf->proxies != NULL) {
+ (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
+ gcf->proxies, gcf->proxy_recursive);
}
#if (NGX_HAVE_INET6)
@@ -293,7 +292,7 @@ static geoipv6_t
ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
{
ngx_addr_t addr;
- ngx_table_elt_t *xfwd;
+ ngx_array_t *xfwd;
in_addr_t addr4;
struct in6_addr addr6;
struct sockaddr_in *sin;
@@ -303,12 +302,11 @@ ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
addr.socklen = r->connection->socklen;
/* addr.name = r->connection->addr_text; */
- xfwd = r->headers_in.x_forwarded_for;
+ xfwd = &r->headers_in.x_forwarded_for;
- if (xfwd != NULL && gcf->proxies != NULL) {
- (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
- xfwd->value.len, gcf->proxies,
- gcf->proxy_recursive);
+ if (xfwd->nelts > 0 && gcf->proxies != NULL) {
+ (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
+ gcf->proxies, gcf->proxy_recursive);
}
switch (addr.sockaddr->sa_family) {
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index a623adc34..eadc8c480 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -2014,32 +2014,44 @@ static ngx_int_t
ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- u_char *p;
+ size_t len;
+ u_char *p;
+ ngx_uint_t i, n;
+ ngx_table_elt_t **h;
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
- if (r->headers_in.x_forwarded_for == NULL) {
+ n = r->headers_in.x_forwarded_for.nelts;
+ h = r->headers_in.x_forwarded_for.elts;
+
+ len = 0;
+
+ for (i = 0; i < n; i++) {
+ len += h[i]->value.len + sizeof(", ") - 1;
+ }
+
+ if (len == 0) {
v->len = r->connection->addr_text.len;
v->data = r->connection->addr_text.data;
return NGX_OK;
}
- v->len = r->headers_in.x_forwarded_for->value.len
- + sizeof(", ") - 1 + r->connection->addr_text.len;
+ len += r->connection->addr_text.len;
- p = ngx_pnalloc(r->pool, v->len);
+ p = ngx_pnalloc(r->pool, len);
if (p == NULL) {
return NGX_ERROR;
}
+ v->len = len;
v->data = p;
- p = ngx_copy(p, r->headers_in.x_forwarded_for->value.data,
- r->headers_in.x_forwarded_for->value.len);
-
- *p++ = ','; *p++ = ' ';
+ for (i = 0; i < n; i++) {
+ p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
+ *p++ = ','; *p++ = ' ';
+ }
ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len);
diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c
index 4531ea51c..ed9c5f9e8 100644
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -107,10 +107,12 @@ ngx_module_t ngx_http_realip_module = {
static ngx_int_t
ngx_http_realip_handler(ngx_http_request_t *r)
{
- u_char *ip, *p;
+ u_char *p;
size_t len;
+ ngx_str_t *value;
ngx_uint_t i, hash;
ngx_addr_t addr;
+ ngx_array_t *xfwd;
ngx_list_part_t *part;
ngx_table_elt_t *header;
ngx_connection_t *c;
@@ -137,19 +139,20 @@ ngx_http_realip_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- len = r->headers_in.x_real_ip->value.len;
- ip = r->headers_in.x_real_ip->value.data;
+ value = &r->headers_in.x_real_ip->value;
+ xfwd = NULL;
break;
case NGX_HTTP_REALIP_XFWD:
- if (r->headers_in.x_forwarded_for == NULL) {
+ xfwd = &r->headers_in.x_forwarded_for;
+
+ if (xfwd->elts == NULL) {
return NGX_DECLINED;
}
- len = r->headers_in.x_forwarded_for->value.len;
- ip = r->headers_in.x_forwarded_for->value.data;
+ value = NULL;
break;
@@ -178,8 +181,8 @@ ngx_http_realip_handler(ngx_http_request_t *r)
&& len == header[i].key.len
&& ngx_strncmp(p, header[i].lowcase_key, len) == 0)
{
- len = header[i].value.len;
- ip = header[i].value.data;
+ value = &header[i].value;
+ xfwd = NULL;
goto found;
}
@@ -192,15 +195,13 @@ found:
c = r->connection;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip);
-
addr.sockaddr = c->sockaddr;
addr.socklen = c->socklen;
/* addr.name = c->addr_text; */
- if (ngx_http_get_forwarded_addr(r, &addr, ip, len, rlcf->from,
+ if (ngx_http_get_forwarded_addr(r, &addr, xfwd, value, rlcf->from,
rlcf->recursive)
- == NGX_OK)
+ != NGX_DECLINED)
{
return ngx_http_realip_set_addr(r, &addr);
}