r194 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Fri Jun 16 12:22:40 CEST 2006


Author: phk
Date: 2006-06-16 12:22:40 +0200 (Fri, 16 Jun 2006)
New Revision: 194

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_fetch.c
   trunk/varnish-cache/bin/varnishd/cache_http.c
   trunk/varnish-cache/bin/varnishd/cache_pool.c
Log:
Initial http_GetHdrField() function.

Improve chunked encoding, allocate big storage chunks and trim the
last one at the end, instead of one storage chunk for each chunk
the remote server sends.

Call RFC2616 policy code.

Store headers from backend in cache and return to client.



Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2006-06-16 10:20:12 UTC (rev 193)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2006-06-16 10:22:40 UTC (rev 194)
@@ -41,6 +41,7 @@
 	TAILQ_ENTRY(storage)	list;
 	unsigned char		*ptr;
 	unsigned		len;
+	unsigned		space;
 	void			*priv;
 	struct stevedore	*stevedore;
 };
@@ -81,6 +82,7 @@
 struct http *http_New(void);
 void http_Delete(struct http *hp);
 int http_GetHdr(struct http *hp, const char *hdr, char **ptr);
+int http_GetHdrField(struct http *hp, const char *hdr, const char *field, char **ptr);
 int http_GetStatus(struct http *hp);
 int http_HdrIs(struct http *hp, const char *hdr, const char *val);
 int http_GetTail(struct http *hp, unsigned len, char **b, char **e);
@@ -124,3 +126,7 @@
 cli_func_t	cli_func_config_unload;
 cli_func_t	cli_func_config_use;
 #endif
+
+/* rfc2616.c */
+void RFC2616_Age(struct http *hp, time_t, time_t);
+

Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_fetch.c	2006-06-16 10:20:12 UTC (rev 193)
+++ trunk/varnish-cache/bin/varnishd/cache_fetch.c	2006-06-16 10:22:40 UTC (rev 194)
@@ -4,6 +4,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <ctype.h>
 #include <inttypes.h>
 #include <unistd.h>
 #include <string.h>
@@ -22,6 +23,17 @@
 #include "vcl_lang.h"
 #include "cache.h"
 
+/*
+ * Chunked encoding is a hack.  We prefer to have a single or a few
+ * large storage objects, and a terribly long list of small ones.
+ * If our stevedore can trim, we alloc big chunks and trim the last one
+ * at the end know the result.
+ *
+ * Good testcase: http://www.washingtonpost.com/
+ */
+#define CHUNK_PREALLOC		(128 * 1024)
+
+/*--------------------------------------------------------------------*/
 static int
 fetch_straight(struct worker *w, struct sess *sp, int fd, struct http *hp, char *b)
 {
@@ -45,7 +57,6 @@
 
 	if (http_GetTail(hp, cl, &b, &e)) {
 		i = e - b;
-		VSL(SLT_Debug, 0, "Fetch_Tail %jd %d", cl, i);
 		memcpy(p, b, i);
 		p += i;
 		cl -= i;
@@ -53,7 +64,6 @@
 
 	while (cl != 0) {
 		i = read(fd, p, cl);
-		VSL(SLT_Debug, 0, "Fetch_Read %jd %d", cl, i);
 		assert(i > 0);
 		p += i;
 		cl -= i;
@@ -68,6 +78,9 @@
 
 }
 
+/*--------------------------------------------------------------------*/
+/* XXX: Cleanup.  It must be possible somehow :-( */
+
 static int
 fetch_chunked(struct worker *w, struct sess *sp, int fd, struct http *hp)
 {
@@ -75,7 +88,7 @@
 	char *b, *q, *e;
 	unsigned char *p;
 	struct storage *st;
-	unsigned u;
+	unsigned u, v;
 	char buf[20];
 	char *bp, *be;
 
@@ -84,46 +97,92 @@
 	i = fcntl(fd, F_SETFL, i);
 
 	be = buf + sizeof buf;
+	bp = buf;
+	st = NULL;
 	while (1) {
-		bp = buf;
 		if (http_GetTail(hp, be - bp, &b, &e)) {
 			memcpy(bp, b, e - b);
 			bp += e - b;
+			*bp = '\0';
 		} else {
 			i = read(fd, bp, be - bp);
 			assert(i >= 0);
 			bp += i;
+			*bp = '\0';
 		}
 		u = strtoul(buf, &q, 16);
-		if (q == NULL || (*q != '\n' && *q != '\r'))
+		if (q == NULL || q == buf)
 			continue;
+		assert(isspace(*q));
+		while (*q == '\t' || *q == ' ')
+			q++;
 		if (*q == '\r')
 			q++;
 		assert(*q == '\n');
 		q++;
 		if (u == 0)
 			break;
-		st = stevedore->alloc(stevedore, u);
-		TAILQ_INSERT_TAIL(&sp->obj->store, st, list);
-		st->len = u;
 		sp->obj->len += u;
-		p = st->ptr;
-		memcpy(p, q, bp - q);
-		p += bp - q;
-		u -= bp - q;
-		if (http_GetTail(hp, u, &b, &e)) {
-			memcpy(p, b, e - b);
-			p += e - b;
-			u -= e - b;
-		}
+
 		while (u > 0) {
-			i = read(fd, p, u);
-			assert(i > 0);
-			u -= i;
-			p += i;
+			if (st != NULL && st->len < st->space) {
+				p = st->ptr + st->len;
+			} else {
+				st = stevedore->alloc(stevedore,
+				    stevedore->trim == NULL ? u : CHUNK_PREALLOC);
+				TAILQ_INSERT_TAIL(&sp->obj->store, st, list);
+				p = st->ptr;
+			}
+			v = st->space - st->len;
+			if (v > u)
+				v = u;
+
+			i = bp - q;
+			if (i == 0) {
+			} else if (v > i) {
+				memcpy(p, q, i);
+				p += i;
+				st->len += i;
+				u -= i;
+				v -= i;
+				q = bp = buf;
+			} else if (i >= v) {
+				memcpy(p, q, v);
+				p += v;
+				st->len += i;
+				q += v;
+				u -= v;
+				v -= v;
+				if (u == 0 && bp > q) {
+					memcpy(buf, q, bp - q);
+					q = bp = buf + (bp - q);
+				}
+			}
+			if (u == 0)
+				break;
+			if (v == 0)
+				continue;
+			if (http_GetTail(hp, v, &b, &e)) {
+				memcpy(p, b, e - b);
+				p += e - b;
+				st->len += e - b;
+				v -= e - b;
+				u -= e - b;
+			}
+			while (v > 0) {
+				i = read(fd, p, v);
+				assert(i > 0);
+				st->len += i;
+				v -= i;
+				u -= i;
+				p += i;
+			}
 		}
 	}
 
+	if (st != NULL && stevedore->trim != NULL)
+		stevedore->trim(st, st->len);
+
 	http_BuildSbuf(2, w->sb, hp);
 
 	vca_write_obj(sp, w->sb);
@@ -141,6 +200,7 @@
 	void *fd_token;
 	struct http *hp;
 	char *b;
+	time_t t_req, t_resp;
 
 	fd = VBE_GetFd(sp->backend, &fd_token);
 	assert(fd != -1);
@@ -150,6 +210,7 @@
 	http_BuildSbuf(1, w->sb, sp->http);
 	i = write(fd, sbuf_data(w->sb), sbuf_len(w->sb));
 	assert(i == sbuf_len(w->sb));
+	time(&t_req);
 
 	/* XXX: copy any contents */
 
@@ -159,15 +220,21 @@
 	 */
 	http_RecvHead(hp, fd, w->eb, NULL, NULL);
 	event_base_loop(w->eb, 0);
+	time(&t_resp);
 	http_Dissect(hp, fd, 2);
 
+	RFC2616_Age(hp, t_req, t_resp);
+
 	switch (http_GetStatus(hp)) {
 	case 200:
+	case 301:
+		http_BuildSbuf(3, w->sb, hp);
 		/* XXX: fill in object from headers */
 		sp->obj->valid = 1;
 		sp->obj->cacheable = 1;
+		sp->obj->header = strdup(sbuf_data(w->sb));
 		break;
-	case 301:
+	case 391:
 		sp->obj->valid = 0;
 		sp->obj->cacheable = 0;
 		break;

Modified: trunk/varnish-cache/bin/varnishd/cache_http.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_http.c	2006-06-16 10:20:12 UTC (rev 193)
+++ trunk/varnish-cache/bin/varnishd/cache_http.c	2006-06-16 10:22:40 UTC (rev 194)
@@ -102,6 +102,39 @@
 }
 
 int
+http_GetHdrField(struct http *hp, const char *hdr, const char *field, char **ptr)
+{
+	char *h;
+	int fl;
+
+	if (!http_GetHdr(hp, hdr, &h))
+		return (0);
+	fl = strlen(field);
+	while (*h) {
+		if (isspace(*h)) {
+			h++;
+			continue;
+		}
+		if (*h == ',') {
+			h++;
+			continue;
+		}
+		if (memcmp(h, field, fl) ||
+		    isalpha(h[fl]) || h[fl] == '-') {
+			while (*h && !(isspace(*h) || *h == ','))
+				h++;
+			continue;
+		}
+		if (h[fl] == '=')
+			*ptr = &h[fl + 1];
+		else
+			*ptr = NULL;
+		return (1);
+	}
+	return (0);
+}
+
+int
 http_HdrIs(struct http *hp, const char *hdr, const char *val)
 {
 	char *p;
@@ -356,7 +389,7 @@
 
 	sbuf_clear(sb);
 	assert(sb != NULL);
-	if (resp == 2) {
+	if (resp == 2 || resp == 3) {
 		sbuf_cat(sb, hp->proto);
 		sbuf_cat(sb, " ");
 		sbuf_cat(sb, hp->status);
@@ -382,6 +415,7 @@
 		sbuf_cat(sb, hp->hdr[u]);
 		sbuf_cat(sb, "\r\n");
 	}
-	sbuf_cat(sb, "\r\n");
+	if (resp != 3)
+		sbuf_cat(sb, "\r\n");
 	sbuf_finish(sb);
 }

Modified: trunk/varnish-cache/bin/varnishd/cache_pool.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_pool.c	2006-06-16 10:20:12 UTC (rev 193)
+++ trunk/varnish-cache/bin/varnishd/cache_pool.c	2006-06-16 10:22:40 UTC (rev 194)
@@ -71,10 +71,9 @@
 
 	sbuf_clear(w->sb);
 	sbuf_printf(w->sb,
-	    "HTTP/1.1 200 OK\r\n"
-	    "Server: Varnish\r\n"
+	    "%sServer: Varnish\r\n"
 	    "Content-Length: %u\r\n"
-	    "\r\n", sp->obj->len);
+	    "\r\n", sp->obj->header, sp->obj->len);
 
 	vca_write_obj(sp, w->sb);
 	return (1);




More information about the varnish-commit mailing list