changeset 4334:f8881d301d62

Fixed: some of $sent_http_* variables may contain header entries that actually haven't been sent to a client. The ngx_http_variable_headers() and ngx_http_variable_unknown_header() functions did not ignore response header entries with zero "hash" field. Thanks to Yichun Zhang (agentzh).
author Valentin Bartenev <vbart@nginx.com>
date Fri, 09 Dec 2011 16:17:12 +0000
parents 352a7b025f2e
children 1003326eccc5
files src/http/ngx_http_variables.c
diffstat 1 files changed, 30 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -644,8 +644,8 @@ static ngx_int_t
 ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v,
     uintptr_t data)
 {
-    ssize_t            len;
-    u_char            *p;
+    size_t             len;
+    u_char            *p, *end;
     ngx_uint_t         i, n;
     ngx_array_t       *a;
     ngx_table_elt_t  **h;
@@ -653,18 +653,30 @@ ngx_http_variable_headers(ngx_http_reque
     a = (ngx_array_t *) ((char *) r + data);
 
     n = a->nelts;
-
-    if (n == 0) {
+    h = a->elts;
+
+    len = 0;
+
+    for (i = 0; i < n; i++) {
+
+        if (h[i]->hash == 0) {
+            continue;
+        }
+
+        len += h[i]->value.len + sizeof("; ") - 1;
+    }
+
+    if (len == 0) {
         v->not_found = 1;
         return NGX_OK;
     }
 
+    len -= sizeof("; ") - 1;
+
     v->valid = 1;
     v->no_cacheable = 0;
     v->not_found = 0;
 
-    h = a->elts;
-
     if (n == 1) {
         v->len = (*h)->value.len;
         v->data = (*h)->value.data;
@@ -672,12 +684,6 @@ ngx_http_variable_headers(ngx_http_reque
         return NGX_OK;
     }
 
-    len = - (ssize_t) (sizeof("; ") - 1);
-
-    for (i = 0; i < n; i++) {
-        len += h[i]->value.len + sizeof("; ") - 1;
-    }
-
     p = ngx_pnalloc(r->pool, len);
     if (p == NULL) {
         return NGX_ERROR;
@@ -686,10 +692,17 @@ ngx_http_variable_headers(ngx_http_reque
     v->len = len;
     v->data = p;
 
+    end = p + len;
+
     for (i = 0; /* void */ ; i++) {
+
+        if (h[i]->hash == 0) {
+            continue;
+        }
+
         p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
 
-        if (i == n - 1) {
+        if (p == end) {
             break;
         }
 
@@ -742,6 +755,10 @@ ngx_http_variable_unknown_header(ngx_htt
             i = 0;
         }
 
+        if (header[i].hash == 0) {
+            continue;
+        }
+
         for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) {
             ch = header[i].key.data[n];