r513 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Thu Jul 20 11:29:45 CEST 2006


Author: phk
Date: 2006-07-20 11:29:45 +0200 (Thu, 20 Jul 2006)
New Revision: 513

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_response.c
Log:
Implement "If-Modified-Since" conditional queries


Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2006-07-20 08:29:14 UTC (rev 512)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2006-07-20 09:29:45 UTC (rev 513)
@@ -56,6 +56,8 @@
 	char			*proto;
 	char			*status;
 	char			*response;
+
+	unsigned		conds;		/* If-* headers present */
 	
 	unsigned		nhdr;
 	char			**hdr;
@@ -151,6 +153,8 @@
 	time_t			entered;
 	time_t			ttl;
 
+	time_t			last_modified;
+
 	char			*header;
 	TAILQ_ENTRY(object)	list;
 
@@ -337,7 +341,7 @@
 /* cache_response.c */
 void RES_Error(struct sess *sp, int error, const char *msg);
 void RES_Flush(struct sess *sp);
-void RES_Write(struct sess *sp, void *ptr, size_t len);
+void RES_Write(struct sess *sp, const void *ptr, size_t len);
 void RES_WriteObj(struct sess *sp);
 
 /* cache_vcl.c */

Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_fetch.c	2006-07-20 08:29:14 UTC (rev 512)
+++ trunk/varnish-cache/bin/varnishd/cache_fetch.c	2006-07-20 09:29:45 UTC (rev 513)
@@ -12,8 +12,10 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
+#include <time.h>
 
 #include "shmlog.h"
+#include "libvarnish.h"
 #include "cache.h"
 
 /*
@@ -211,6 +213,8 @@
 	vc = sp->vbc;
 	hp = sp->bkd_http;
 
+	if (http_GetHdr(hp, "Last-Modified", &b))
+		sp->obj->last_modified = TIM_parse(b);
 	http_BuildSbuf(sp->fd, Build_Reply, w->sb, hp);
 	if (body) {
 		if (http_GetHdr(hp, "Content-Length", &b))

Modified: trunk/varnish-cache/bin/varnishd/cache_http.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_http.c	2006-07-20 08:29:14 UTC (rev 512)
+++ trunk/varnish-cache/bin/varnishd/cache_http.c	2006-07-20 09:29:45 UTC (rev 513)
@@ -156,7 +156,10 @@
 	return (strtoul(hp->status, NULL /* XXX */, 10));
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Dissect the headers of the HTTP protocol message.
+ * Detect conditionals (headers which start with '^[Ii][Ff]-')
+ */
 
 static int
 http_dissect_hdrs(struct http *hp, int fd, char *p)
@@ -167,6 +170,7 @@
 		p++;
 
 	hp->nhdr = 0;
+	hp->conds = 0;
 	r = NULL;		/* For FlexeLint */
 	assert(p < hp->v);	/* http_header_complete() guarantees this */
 	for (; p < hp->v; p = r) {
@@ -179,6 +183,11 @@
 		if (p == q)
 			break;
 
+		if ((p[0] == 'i' || p[0] == 'I') &&
+		    (p[1] == 'f' || p[1] == 'F') &&
+		    p[2] == '-') 
+			hp->conds = 1;
+
 		if (hp->nhdr < heritage.mem_http_headers) {
 			hp->hdr[hp->nhdr++] = p;
 			VSLR(SLT_Header, fd, p, q);

Modified: trunk/varnish-cache/bin/varnishd/cache_response.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_response.c	2006-07-20 08:29:14 UTC (rev 512)
+++ trunk/varnish-cache/bin/varnishd/cache_response.c	2006-07-20 09:29:45 UTC (rev 513)
@@ -93,20 +93,76 @@
 }
 
 void
-RES_Write(struct sess *sp, void *ptr, size_t len)
+RES_Write(struct sess *sp, const void *ptr, size_t len)
 {
 
 	if (sp->fd < 0 || len == 0)
 		return;
+	if (len == -1)
+		len = strlen(ptr);
 	if (sp->wrk->niov == MAX_IOVS)
 		RES_Flush(sp);
 	if (sp->fd < 0)
 		return;
-	sp->wrk->iov[sp->wrk->niov].iov_base = ptr;
+	sp->wrk->iov[sp->wrk->niov].iov_base = (void*)(uintptr_t)ptr;
 	sp->wrk->iov[sp->wrk->niov++].iov_len = len;
 	sp->wrk->liov += len;
 }
 
+/*--------------------------------------------------------------------*/
+
+static void
+res_do_304(struct sess *sp, char *p)
+{
+	struct sbuf *sb;
+
+	sb = sp->wrk->sb;
+	sbuf_clear(sb);
+
+	VSL(SLT_Status, sp->fd, "%u", 304);
+	VSL(SLT_Length, sp->fd, "%u", 0);
+	RES_Write(sp, "HTTP/1.1 304 Not Modified\r\n", -1);
+	RES_Write(sp, "Via: 1.1 varnish\r\n", -1);
+	RES_Write(sp, "Last-Modified: ", -1);
+	RES_Write(sp, p, -1);
+	RES_Write(sp, "\r\n", -1);
+	if (strcmp(sp->http->proto, "HTTP/1.1")) 
+		RES_Write(sp, "Connection: close\r\n", -1);
+	sbuf_printf(sb, "X-Varnish: xid %u\r\n", sp->obj->xid);
+	sbuf_printf(sb, "\r\n");
+	sbuf_finish(sb);
+	RES_Write(sp, sbuf_data(sb), sbuf_len(sb));
+	RES_Flush(sp);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+res_do_conds(struct sess *sp)
+{
+	char *p;
+	time_t ims;
+
+	if (sp->obj->last_modified > 0 &&
+	    http_GetHdr(sp->http, "If-Modified-Since", &p)) {
+		ims = TIM_parse(p);
+		if (ims > sp->t_req)	/* [RFC2616 14.25] */
+			return (0);
+		if (ims > sp->obj->last_modified) {
+			VSL(SLT_Debug, sp->fd,
+			    "Cond: %d > %d ", sp->obj->last_modified, ims);
+			return (0);
+		}
+		VSL(SLT_Debug, sp->fd,
+		    "Cond: %d <= %d", sp->obj->last_modified, ims);
+		res_do_304(sp, p);
+		return (1);
+	}
+	return (0);
+}
+
+/*--------------------------------------------------------------------*/
+
 void
 RES_WriteObj(struct sess *sp)
 {
@@ -118,6 +174,9 @@
 
 	sb = sp->wrk->sb;
 
+	if (sp->obj->response == 200 && sp->http->conds && res_do_conds(sp))
+		return;
+		
 	VSL(SLT_Status, sp->fd, "%u", sp->obj->response);
 	VSL(SLT_Length, sp->fd, "%u", sp->obj->len);
 




More information about the varnish-commit mailing list