r302 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Tue Jul 4 21:36:00 CEST 2006


Author: phk
Date: 2006-07-04 21:36:00 +0200 (Tue, 04 Jul 2006)
New Revision: 302

Modified:
   trunk/varnish-cache/bin/varnishd/cache_http.c
Log:

Fix pipelining.

A braino in http_Dissect() resulted in an off-by-one error
(protected with assert now)

Move any remaning bytes in buffer to front and check for
a complete header before arming the eventloop on the
session.



Modified: trunk/varnish-cache/bin/varnishd/cache_http.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_http.c	2006-07-04 14:52:54 UTC (rev 301)
+++ trunk/varnish-cache/bin/varnishd/cache_http.c	2006-07-04 19:36:00 UTC (rev 302)
@@ -291,11 +291,34 @@
 			VSLR(SLT_LostHeader, fd, p, q);
 		}
 	}
-	if (*++p == '\r')
+	assert(hp->t == r);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+http_header_complete(struct http *hp)
+{
+	char *p;
+
+	p = hp->s;
+	while (1) {
+		/* XXX: we could save location of all linebreaks for later */
+		p = strchr(p, '\n');
+		if (p == NULL)
+			return (0);
 		p++;
+		if (*p == '\r')
+			p++;
+		if (*p != '\n')
+			continue;
+		break;
+	}
 	hp->t = ++p;
+	return (1);
 }
 
+
 /*--------------------------------------------------------------------*/
 
 #include <errno.h>
@@ -330,22 +353,9 @@
 
 	hp->v += i;
 	*hp->v = '\0';
+	if (!http_header_complete(hp))
+		return;
 
-	p = hp->s;
-	while (1) {
-		/* XXX: we could save location of all linebreaks for later */
-		p = strchr(p, '\n');
-		if (p == NULL)
-			return;
-		p++;
-		if (*p == '\r')
-			p++;
-		if (*p != '\n')
-			continue;
-		break;
-	}
-	hp->t = ++p;
-
 	event_del(&hp->ev);
 	if (hp->callback != NULL)
 		hp->callback(hp->arg, 1);
@@ -356,9 +366,18 @@
 void
 http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg)
 {
+	unsigned l;
 
 	assert(hp != NULL);
-	assert(hp->t == hp->s || hp->t == hp->v);	/* XXX pipelining */
+	if (hp->t > hp->s && hp->t < hp->v) {
+		l = hp->v - hp->t;
+		memmove(hp->s, hp->t, l);
+		hp->v = hp->s + l;
+		if (http_header_complete(hp)) {
+			func(arg, 1);
+			return;
+		}
+	}
 	hp->callback = func;
 	hp->arg = arg;
 	hp->v = hp->s;




More information about the varnish-commit mailing list