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