Commit b312abd1 authored by Tollef Fog Heen's avatar Tollef Fog Heen

Add support for logging response headers in varnishncsa

parent 49c62a56
...@@ -103,7 +103,8 @@ static struct logline { ...@@ -103,7 +103,8 @@ static struct logline {
int active; /* Is log line in an active trans */ int active; /* Is log line in an active trans */
int complete; /* Is log line complete */ int complete; /* Is log line complete */
uint64_t bitmap; /* Bitmap for regex matches */ uint64_t bitmap; /* Bitmap for regex matches */
VTAILQ_HEAD(, hdr) headers; VTAILQ_HEAD(, hdr) req_headers; /* Request headers */
VTAILQ_HEAD(, hdr) resp_headers; /* Response headers */
} **ll; } **ll;
struct VSM_data *vd; struct VSM_data *vd;
...@@ -190,10 +191,23 @@ trimline(const char *str, const char *end) ...@@ -190,10 +191,23 @@ trimline(const char *str, const char *end)
} }
static char * static char *
get_header(struct logline *l, const char *name) req_header(struct logline *l, const char *name)
{ {
struct hdr *h; struct hdr *h;
VTAILQ_FOREACH(h, &l->headers, list) { VTAILQ_FOREACH(h, &l->req_headers, list) {
if (strcasecmp(h->key, name) == 0) {
return h->value;
break;
}
}
return NULL;
}
static char *
resp_header(struct logline *l, const char *name)
{
struct hdr *h;
VTAILQ_FOREACH(h, &l->resp_headers, list) {
if (strcasecmp(h->key, name) == 0) { if (strcasecmp(h->key, name) == 0) {
return h->value; return h->value;
break; break;
...@@ -216,8 +230,14 @@ clean_logline(struct logline *lp) ...@@ -216,8 +230,14 @@ clean_logline(struct logline *lp)
freez(lp->df_s); freez(lp->df_s);
freez(lp->df_u); freez(lp->df_u);
freez(lp->df_ttfb); freez(lp->df_ttfb);
VTAILQ_FOREACH_SAFE(h, &lp->headers, list, h2) { VTAILQ_FOREACH_SAFE(h, &lp->req_headers, list, h2) {
VTAILQ_REMOVE(&lp->headers, h, list); VTAILQ_REMOVE(&lp->req_headers, h, list);
freez(h->key);
freez(h->value);
freez(h);
}
VTAILQ_FOREACH_SAFE(h, &lp->resp_headers, list, h2) {
VTAILQ_REMOVE(&lp->resp_headers, h, list);
freez(h->key); freez(h->key);
freez(h->value); freez(h->value);
freez(h); freez(h);
...@@ -326,7 +346,7 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec, ...@@ -326,7 +346,7 @@ collect_backend(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
l = strlen(split); l = strlen(split);
h->key = trimline(ptr, split-1); h->key = trimline(ptr, split-1);
h->value = trimline(split+1, split+l-1); h->value = trimline(split+1, split+l-1);
VTAILQ_INSERT_HEAD(&lp->headers, h, list); VTAILQ_INSERT_HEAD(&lp->req_headers, h, list);
} }
break; break;
...@@ -415,10 +435,12 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec, ...@@ -415,10 +435,12 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
lp->df_s = trimline(ptr, end); lp->df_s = trimline(ptr, end);
break; break;
case SLT_TxHeader:
case SLT_RxHeader: case SLT_RxHeader:
if (!lp->active) if (!lp->active)
break; break;
if (isprefix(ptr, "authorization:", end, &next) && if (tag == SLT_RxHeader &&
isprefix(ptr, "authorization:", end, &next) &&
isprefix(next, "basic", end, &next)) { isprefix(next, "basic", end, &next)) {
free(lp->df_u); free(lp->df_u);
lp->df_u = trimline(next, end); lp->df_u = trimline(next, end);
...@@ -431,7 +453,10 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec, ...@@ -431,7 +453,10 @@ collect_client(struct logline *lp, enum VSL_tag_e tag, unsigned spec,
AN(split); AN(split);
h->key = trimline(ptr, split); h->key = trimline(ptr, split);
h->value = trimline(split+1, end); h->value = trimline(split+1, end);
VTAILQ_INSERT_HEAD(&lp->headers, h, list); if (tag == SLT_RxHeader)
VTAILQ_INSERT_HEAD(&lp->req_headers, h, list);
else
VTAILQ_INSERT_HEAD(&lp->resp_headers, h, list);
} }
break; break;
...@@ -601,10 +626,10 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, ...@@ -601,10 +626,10 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd,
*/ */
VSB_cat(os, lp->df_m); VSB_cat(os, lp->df_m);
VSB_putc(os, ' '); VSB_putc(os, ' ');
if (get_header(lp, "Host")) { if (req_header(lp, "Host")) {
if (strncmp(get_header(lp, "Host"), "http://", 7) != 0) if (strncmp(req_header(lp, "Host"), "http://", 7) != 0)
VSB_cat(os, "http://"); VSB_cat(os, "http://");
VSB_cat(os, get_header(lp, "Host")); VSB_cat(os, req_header(lp, "Host"));
} }
VSB_cat(os, lp->df_U); VSB_cat(os, lp->df_U);
VSB_cat(os, lp->df_q ? lp->df_q : ""); VSB_cat(os, lp->df_q ? lp->df_q : "");
...@@ -659,11 +684,17 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd, ...@@ -659,11 +684,17 @@ h_ncsa(void *priv, enum VSL_tag_e tag, unsigned fd,
tmp++; tmp++;
type = *tmp; type = *tmp;
memcpy(fname, p+1, tmp-p-2); memcpy(fname, p+1, tmp-p-2);
fname[tmp-p-2] = 0;
} }
switch (type) { switch (type) {
case 'i': case 'i':
h = get_header(lp, fname); h = req_header(lp, fname);
VSB_cat(os, h ? h : "-");
p = tmp;
break;
case 'o':
h = resp_header(lp, fname);
VSB_cat(os, h ? h : "-"); VSB_cat(os, h ? h : "-");
p = tmp; p = tmp;
break; break;
......
...@@ -79,6 +79,9 @@ The following options are available: ...@@ -79,6 +79,9 @@ The following options are available:
%q %q
The query string, if no query string exists, an empty string. The query string, if no query string exists, an empty string.
%{X}o
The contents of response header line X.
%r %r
The first line of the request The first line of the request
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment