diff src/http/modules/ngx_http_proxy_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 7fa7e60a7f66
children 886800caf360 8c866e31bc39
line wrap: on
line diff
--- 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;
-
-    p = ngx_pnalloc(r->pool, v->len);
+    len += r->connection->addr_text.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);