Commit 2175fdf6 authored by Martin Blix Grydeland's avatar Martin Blix Grydeland

Merge r5162: Make varnishncsa only consider log information between the open...

Merge r5162: Make varnishncsa only consider log information between the open and close log tags for a connection, and clear the collected log data on seeing the open tag. This resolves an issue with log data where varnishncsa would consider a set of data as bogus because of extra data in the log belonging to the previous connection.

Support case 164.



git-svn-id: http://www.varnish-cache.org/svn/branches/2.1@5164 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent e574df8e
......@@ -96,7 +96,8 @@ static struct logline {
char *df_s; /* %s, Status */
struct tm df_t; /* %t, Date and time */
char *df_u; /* %u, Remote user */
int bogus; /* bogus request */
int active; /* Is log line in an active trans */
int complete; /* Is log line complete */
} **ll;
static size_t nll;
......@@ -177,6 +178,25 @@ trimline(const char *str, const char *end)
return (p);
}
static void
clean_logline(struct logline *lp)
{
#define freez(x) do { if (x) free(x); x = NULL; } while (0);
freez(lp->df_H);
freez(lp->df_Host);
freez(lp->df_Referer);
freez(lp->df_Uq);
freez(lp->df_User_agent);
freez(lp->df_X_Forwarded_For);
freez(lp->df_b);
freez(lp->df_h);
freez(lp->df_m);
freez(lp->df_s);
freez(lp->df_u);
#undef freez
memset(lp, 0, sizeof *lp);
}
static int
collect_backend(struct logline *lp, enum shmlogtag tag, unsigned spec,
const char *ptr, unsigned len)
......@@ -188,9 +208,12 @@ collect_backend(struct logline *lp, enum shmlogtag tag, unsigned spec,
switch (tag) {
case SLT_BackendOpen:
if (lp->df_h != NULL)
lp->bogus = 1;
else
if(lp->active || lp->df_h != NULL) {
/* New start for active line,
clean it and start from scratch */
clean_logline(lp);
}
lp->active = 1;
if (isprefix(ptr, "default", end, &next))
lp->df_h = trimfield(next, end);
else
......@@ -198,42 +221,59 @@ collect_backend(struct logline *lp, enum shmlogtag tag, unsigned spec,
break;
case SLT_TxRequest:
if (lp->df_m != NULL)
lp->bogus = 1;
else
if(!lp->active)
break;
if (lp->df_m != NULL) {
clean_logline(lp);
break;
}
lp->df_m = trimline(ptr, end);
break;
case SLT_TxURL:
if (lp->df_Uq != NULL)
lp->bogus = 1;
else
if(!lp->active)
break;
if(lp->df_Uq != NULL) {
clean_logline(lp);
break;
}
lp->df_Uq = trimline(ptr, end);
break;
case SLT_TxProtocol:
if (lp->df_H != NULL)
lp->bogus = 1;
else
if(!lp->active)
break;
if (lp->df_H != NULL) {
clean_logline(lp);
break;
}
lp->df_H = trimline(ptr, end);
break;
case SLT_RxStatus:
if (lp->df_s != NULL)
lp->bogus = 1;
else
if(!lp->active)
break;
if (lp->df_s != NULL) {
clean_logline(lp);
break;
}
lp->df_s = trimline(ptr, end);
break;
case SLT_RxHeader:
if(!lp->active)
break;
if (isprefix(ptr, "content-length:", end, &next))
lp->df_b = trimline(next, end);
else if (isprefix(ptr, "date:", end, &next) &&
strptime(next, "%a, %d %b %Y %T", &lp->df_t) == NULL)
lp->bogus = 1;
strptime(next, "%a, %d %b %Y %T", &lp->df_t) == NULL) {
clean_logline(lp);
}
break;
case SLT_TxHeader:
if(!lp->active)
break;
if (isprefix(ptr, "user-agent:", end, &next))
lp->df_User_agent = trimline(next, end);
else if (isprefix(ptr, "referer:", end, &next))
......@@ -249,14 +289,16 @@ collect_backend(struct logline *lp, enum shmlogtag tag, unsigned spec,
case SLT_BackendReuse:
case SLT_BackendClose:
if(!lp->active)
break;
/* got it all */
return (0);
lp->complete = 1;
break;
default:
break;
}
/* more to come */
return (1);
}
......@@ -273,41 +315,57 @@ collect_client(struct logline *lp, enum shmlogtag tag, unsigned spec,
switch (tag) {
case SLT_ReqStart:
if (lp->df_h != NULL)
lp->bogus = 1;
else
if(lp->active || lp->df_h != NULL) {
/* New start for active line,
clean it and start from scratch */
clean_logline(lp);
}
lp->active = 1;
lp->df_h = trimfield(ptr, end);
break;
case SLT_RxRequest:
if (lp->df_m != NULL)
lp->bogus = 1;
else
if(!lp->active)
break;
if (lp->df_m != NULL) {
clean_logline(lp);
break;
}
lp->df_m = trimline(ptr, end);
break;
case SLT_RxURL:
if (lp->df_Uq != NULL)
lp->bogus = 1;
else
if(!lp->active)
break;
if (lp->df_Uq != NULL) {
clean_logline(lp);
break;
}
lp->df_Uq = trimline(ptr, end);
break;
case SLT_RxProtocol:
if (lp->df_H != NULL)
lp->bogus = 1;
else
if(!lp->active)
break;
if (lp->df_H != NULL) {
clean_logline(lp);
break;
}
lp->df_H = trimline(ptr, end);
break;
case SLT_TxStatus:
if(!lp->active)
break;
if (lp->df_s != NULL)
lp->bogus = 1;
clean_logline(lp);
else
lp->df_s = trimline(ptr, end);
break;
case SLT_RxHeader:
if(!lp->active)
break;
if (isprefix(ptr, "user-agent:", end, &next))
lp->df_User_agent = trimline(next, end);
else if (isprefix(ptr, "referer:", end, &next))
......@@ -322,33 +380,42 @@ collect_client(struct logline *lp, enum shmlogtag tag, unsigned spec,
break;
case SLT_Length:
if (lp->df_b != NULL)
lp->bogus = 1;
else
if(!lp->active)
break;
if (lp->df_b != NULL) {
clean_logline(lp);
break;
}
lp->df_b = trimline(ptr, end);
break;
case SLT_SessionClose:
if(!lp->active)
break;
if (strncmp(ptr, "pipe", len) == 0 ||
strncmp(ptr, "error", len) == 0)
lp->bogus = 1;
strncmp(ptr, "error", len) == 0) {
clean_logline(lp);
break;
}
break;
case SLT_ReqEnd:
if(!lp->active)
break;
if (sscanf(ptr, "%*u %*u.%*u %ld.", &l) != 1) {
lp->bogus = 1;
} else {
clean_logline(lp);
break;
}
t = l;
localtime_r(&t, &lp->df_t);
}
/* got it all */
return (0);
lp->complete = 1;
break;
default:
break;
}
/* more to come */
return (1);
}
......@@ -379,23 +446,27 @@ h_ncsa(void *priv, enum shmlogtag tag, unsigned fd,
lp = ll[fd];
if (spec & VSL_S_BACKEND) {
if (collect_backend(lp, tag, spec, ptr, len))
return (reopen);
collect_backend(lp, tag, spec, ptr, len);
} else if (spec & VSL_S_CLIENT) {
if (collect_client(lp, tag, spec, ptr, len))
return (reopen);
collect_client(lp, tag, spec, ptr, len);
} else {
/* huh? */
return (reopen);
}
if(!lp->complete)
return (reopen);
#if 0
/* non-optional fields */
if (!lp->df_m || !lp->df_Uq || !lp->df_H || !lp->df_s)
lp->bogus = 1;
if (!lp->df_m || !lp->df_Uq || !lp->df_H || !lp->df_s) {
clean_logline(lp);
return (reopen);
}
#endif
if (!lp->bogus) {
/* We have a complete data set - log a line */
fo = priv;
/* %h */
......@@ -461,23 +532,9 @@ h_ncsa(void *priv, enum shmlogtag tag, unsigned fd,
/* flush the stream */
fflush(fo);
}
/* clean up */
#define freez(x) do { if (x) free(x); x = NULL; } while (0);
freez(lp->df_H);
freez(lp->df_Host);
freez(lp->df_Referer);
freez(lp->df_Uq);
freez(lp->df_User_agent);
freez(lp->df_X_Forwarded_For);
freez(lp->df_b);
freez(lp->df_h);
freez(lp->df_m);
freez(lp->df_s);
freez(lp->df_u);
#undef freez
memset(lp, 0, sizeof *lp);
clean_logline(lp);
return (reopen);
}
......
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