[PATCH] Add log variables $http_all and $sent_http_all

Jonh Wendell jonh.wendell at gmail.com
Wed Jul 29 20:15:24 UTC 2015


 src/http/ngx_http_header_filter_module.c |   5 +
 src/http/ngx_http_request.h              |   2 +
 src/http/ngx_http_variables.c            |  92 ++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 0 deletions(-)


# HG changeset patch
# User Jonh Wendell <jonh.wendell at gmail.com>
# Date 1438199955 10800
#      Wed Jul 29 16:59:15 2015 -0300
# Node ID 2412f965360cdbf9d15280e8ee9fa1a28a3c86ca
# Parent  341e4303d25be159d4773b819d0ec055ba711afb
Add log variables $http_all and $sent_http_all

These are meant to log the entire request and response
headers, respectively.

There are cases when we want to log the whole request (or response)
headers, for example, when we don't know in advance the
field the client sends. Currently we must know exactly the
header fields we want to log.

This patch adds these two variables that contains

$http_all: all request headers as received from client
$sent_http_all: all response headers as sent to the client

Closes #426.

diff -r 341e4303d25b -r 2412f965360c src/http/ngx_http_header_filter_module.c
--- a/src/http/ngx_http_header_filter_module.c	Thu Jul 16 14:20:48 2015 +0300
+++ b/src/http/ngx_http_header_filter_module.c	Wed Jul 29 16:59:15 2015 -0300
@@ -608,6 +608,11 @@
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "%*s", (size_t) (b->last - b->pos), b->pos);
 
+    /* prepare the complete headers for eventual logging - strip out the last "\r\n" */
+    r->headers_out.final_response.len = b->last - b->pos - (sizeof(CRLF) - 1);
+    r->headers_out.final_response.data = ngx_palloc(r->pool, r->headers_out.final_response.len);
+    ngx_memcpy(r->headers_out.final_response.data, b->pos, r->headers_out.final_response.len);
+
     /* the end of HTTP header */
     *b->last++ = CR; *b->last++ = LF;
 
diff -r 341e4303d25b -r 2412f965360c src/http/ngx_http_request.h
--- a/src/http/ngx_http_request.h	Thu Jul 16 14:20:48 2015 +0300
+++ b/src/http/ngx_http_request.h	Wed Jul 29 16:59:15 2015 -0300
@@ -272,6 +272,8 @@
     off_t                             content_length_n;
     time_t                            date_time;
     time_t                            last_modified_time;
+
+    ngx_str_t                         final_response;
 } ngx_http_headers_out_t;
 
 
diff -r 341e4303d25b -r 2412f965360c src/http/ngx_http_variables.c
--- a/src/http/ngx_http_variables.c	Thu Jul 16 14:20:48 2015 +0300
+++ b/src/http/ngx_http_variables.c	Wed Jul 29 16:59:15 2015 -0300
@@ -100,6 +100,10 @@
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_http_all(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_sent_http_all(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 
 static ngx_int_t ngx_http_variable_sent_content_type(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
@@ -174,6 +178,9 @@
     { ngx_string("http_cookie"), NULL, ngx_http_variable_cookies,
       offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 },
 
+    { ngx_string("http_all"), NULL, ngx_http_variable_http_all, 0, 0, 0 },
+    { ngx_string("sent_http_all"), NULL, ngx_http_variable_sent_http_all, 0, 0, 0 },
+
     { ngx_string("content_length"), NULL, ngx_http_variable_content_length,
       0, 0, 0 },
 
@@ -1712,6 +1719,91 @@
 
 
 static ngx_int_t
+ngx_http_variable_sent_http_all(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    v->len = r->headers_out.final_response.len;
+    v->data = r->headers_out.final_response.data;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_variable_http_all(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    ngx_uint_t        i;
+    ngx_list_part_t  *part;
+    ngx_table_elt_t  *header;
+    u_char           *buf;
+
+    v->len = 0;
+
+    part = &r->headers_in.headers.part;
+    header = part->elts;
+    for (i = 0; /* void */ ; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            header = part->elts;
+            i = 0;
+        }
+
+        if (header[i].hash == 0) {
+            continue;
+        }
+
+        v->len += header[i].key.len + header[i].value.len + sizeof(": \r\n") - 1;
+    }
+
+    buf = ngx_pnalloc(r->pool, v->len);
+    if (buf == NULL) {
+        return NGX_ERROR;
+    }
+    v->data = buf;
+
+    part = &r->headers_in.headers.part;
+    header = part->elts;
+    for (i = 0; /* void */ ; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            header = part->elts;
+            i = 0;
+        }
+
+        if (header[i].hash == 0) {
+            continue;
+        }
+
+        buf = ngx_sprintf(buf, "%V: %V\r\n", &header[i].key, &header[i].value);
+    }
+
+    if (v->len > 0) {
+        v->len -= sizeof(CRLF) - 1;
+    }
+
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_variable_sent_content_type(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {



More information about the nginx-devel mailing list