r5758 - trunk/varnish-cache/bin/varnishd

phk at varnish-cache.org phk at varnish-cache.org
Tue Jan 18 12:08:46 CET 2011


Author: phk
Date: 2011-01-18 12:08:46 +0100 (Tue, 18 Jan 2011)
New Revision: 5758

Modified:
   trunk/varnish-cache/bin/varnishd/cache_esi_deliver.c
   trunk/varnish-cache/bin/varnishd/cache_esi_parse.c
Log:
Calculate and emit CRC32 checksum for all verbatim bites,
we need this to produce the correct final CRC32 for gzip'ed
ESI documents.



Modified: trunk/varnish-cache/bin/varnishd/cache_esi_deliver.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_esi_deliver.c	2011-01-18 11:07:57 UTC (rev 5757)
+++ trunk/varnish-cache/bin/varnishd/cache_esi_deliver.c	2011-01-18 11:08:46 UTC (rev 5758)
@@ -39,6 +39,7 @@
 #include "cache_esi.h"
 #include "vend.h"
 #include "vct.h"
+#include "zlib.h"
 #include "stevedore.h"
 
 /*--------------------------------------------------------------------*/
@@ -159,7 +160,7 @@
 		p += 9;
 		break;
 	default:
-		printf("%d\n",(*p & 15));
+		printf("Illegal Length %d %d\n", *p, (*p & 15));
 		INCOMPL();
 	}
 	*pp = p;
@@ -174,6 +175,7 @@
 	uint8_t *p, *e, *q, *r;
 	unsigned off;
 	ssize_t l;
+	uint32_t crc, crc_ref;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	st = sp->obj->esidata;
@@ -190,8 +192,16 @@
 		case VEC_V2:
 		case VEC_V8:
 			l = ved_decode_len(&p);
+			crc = vbe32dec(p);
+			p += 4;
 			q = (void*)strchr((const char*)p, '\0');
 			assert (q > p);
+			crc_ref = crc32(0L, Z_NULL, 0);
+			crc_ref = crc32(crc_ref, st->ptr + off, l);
+			if (crc_ref != crc) {
+				printf("CRC Mismatch %08x %08x\n", crc_ref, crc);
+			}
+			xxxassert(crc_ref == crc);
 			esi_sendchunk(sp, p, q - p, st->ptr + off, l);
 			off += l;
 			p = q + 1;

Modified: trunk/varnish-cache/bin/varnishd/cache_esi_parse.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_esi_parse.c	2011-01-18 11:07:57 UTC (rev 5757)
+++ trunk/varnish-cache/bin/varnishd/cache_esi_parse.c	2011-01-18 11:08:46 UTC (rev 5758)
@@ -39,6 +39,7 @@
 #include "cache_esi.h"
 #include "vend.h"
 #include "vct.h"
+#include "zlib.h"
 #include "stevedore.h"
 
 #ifndef OLD_ESI
@@ -77,6 +78,9 @@
 	ssize_t			o_skip;
 	ssize_t			o_pending;
 	ssize_t			o_total;
+	uint32_t		crc;
+	ssize_t			o_crc;
+	uint32_t		crcp;
 
 const char		*hack_p;
 	const char		*ver_p;
@@ -252,78 +256,138 @@
 } 
 
 static void
-vep_emit_skip(struct vep_state *vep, ssize_t *l)
+vep_emit_skip(struct vep_state *vep, ssize_t l)
 {
 
-	assert(*l > 0);
 	if (params->esi_syntax & 0x20) {
-		Debug("---> SKIP(%jd)\n", (intmax_t)*l);
+		Debug("---> SKIP(%jd)\n", (intmax_t)l);
 	}
-	vep_emit_len(vep, *l, VEC_S1, VEC_S2, VEC_S8);
-	vep->o_total += *l;
-	*l = 0;
+	vep_emit_len(vep, l, VEC_S1, VEC_S2, VEC_S8);
 } 
 
 static void
-vep_emit_verbatim(struct vep_state *vep, ssize_t *l)
+vep_emit_verbatim(struct vep_state *vep, ssize_t l)
 {
+	uint8_t buf[4];
 
-	assert(*l > 0);
 	if (params->esi_syntax & 0x20) {
-		Debug("---> VERBATIM(%jd)\n", (intmax_t)*l);
+		Debug("---> VERBATIM(%jd)\n", (intmax_t)l);
 	}
-	vep_emit_len(vep, *l, VEC_V1, VEC_V2, VEC_V8);
-	vsb_printf(vep->vsb, "%lx\r\n%c", *l, 0);
+	vep_emit_len(vep, l, VEC_V1, VEC_V2, VEC_V8);
+	vbe32enc(buf, vep->crc);
+	vsb_bcat(vep->vsb, buf, sizeof buf);
+	vsb_printf(vep->vsb, "%lx\r\n%c", l, 0);
+} 
+
+static void
+vep_emit_common(struct vep_state *vep, ssize_t *l, int skip)
+{
+	assert(*l > 0);
+	assert(*l == vep->o_crc);
+
+	if (skip)
+		vep_emit_skip(vep, *l);
+	else
+		vep_emit_verbatim(vep, *l);
+
+	vep->crc = crc32(0L, Z_NULL, 0);
+	vep->o_crc = 0;
 	vep->o_total += *l;
 	*l = 0;
-} 
+}
 
+/*---------------------------------------------------------------------
+ *
+ */
+
 static void
-vep_mark_verbatim(struct vep_state *vep, const char *p)
+vep_mark_common(struct vep_state *vep, const char *p, int skip)
 {
 	ssize_t l;
 
+	/*
+	 * If we changed mode, emit whatever the opposite mode
+	 * assembled before the pending bytes.
+	 */
+	if (skip && vep->o_verbatim > 0)
+		vep_emit_common(vep, &vep->o_verbatim, 0);
+	else if (!skip && vep->o_skip > 0)
+		vep_emit_common(vep, &vep->o_skip, 1);
+
+	/* In debug mode, the pending bytes are emitted separately.  */
+	if ((params->esi_syntax & 0x10) && vep->o_pending) {
+		vep->o_crc = vep->o_pending;
+		vep->crc = vep->crcp;
+		vep->crcp = crc32(0L, Z_NULL, 0);
+		vep_emit_common(vep, &vep->o_pending, skip);
+	}
+
+	/* Transfer pending bytes CRC into active mode.  */
+	if (vep->o_pending) {
+		if (vep->o_crc == 0) {
+			vep->crc = vep->crcp;
+			vep->o_crc = vep->o_pending;
+		} else {
+			vep->crc = crc32_combine(vep->crc,
+			    vep->crcp, vep->o_pending);
+			vep->o_crc += vep->o_pending;
+		}
+		vep->crcp = crc32(0L, Z_NULL, 0);
+	}
+
+	/*
+	 * Process this bit of input
+	 */
 	AN(vep->ver_p);
 	l = p - vep->ver_p;
+	assert(l >= 0);
+	vep->crc = crc32(vep->crc, (const void*)vep->ver_p, l);
+	vep->o_crc += l;
 	vep->ver_p = p;
-	assert(l >= 0);
-	if (params->esi_syntax & 0x10) {
-		if (vep->o_pending)
-			vep_emit_verbatim(vep, &vep->o_pending);
-		if (l)
-			vep_emit_verbatim(vep, &l);
+
+	if ((params->esi_syntax & 0x10) && l > 0) {
+		/* Emit right away if debug mode */
+		vep_emit_common(vep, &l, skip);
+	} else if (skip) {
+		vep->o_skip += vep->o_pending;
+		vep->o_skip += l;
 	} else {
-		if (vep->o_skip > 0) 
-			vep_emit_skip(vep, &vep->o_skip);
 		vep->o_verbatim += vep->o_pending;
-		vep->o_pending = 0;
 		vep->o_verbatim += l;
 	}
+	vep->o_pending = 0;
+}
+
+
+static void
+vep_mark_verbatim(struct vep_state *vep, const char *p)
+{
+	vep_mark_common(vep, p, 0);
 } 
 
 static void
 vep_mark_skip(struct vep_state *vep, const char *p)
 {
+	vep_mark_common(vep, p, 1);
+} 
+
+static void
+vep_mark_pending(struct vep_state *vep, const char *p)
+{
 	ssize_t l;
 
 	AN(vep->ver_p);
 	l = p - vep->ver_p;
+	if (l == 0)
+		return;
+	assert(l >= 0);
+	vep->crcp = crc32(vep->crcp, (const void *)vep->ver_p, l);
 	vep->ver_p = p;
-	assert(l >= 0);
-	if (params->esi_syntax & 0x10) {
-		if (vep->o_pending) 
-			vep_emit_skip(vep, &vep->o_pending);
-		if (l)
-			vep_emit_skip(vep, &l);
-	} else {
-		if (vep->o_verbatim > 0) 
-			vep_emit_verbatim(vep, &vep->o_verbatim);
-		vep->o_skip += vep->o_pending;
-		vep->o_pending = 0;
-		vep->o_skip += l;
-	}
-} 
 
+	vep->o_pending += l;
+	fflush(stdout);
+}
+
 /*---------------------------------------------------------------------
  */
 
@@ -389,9 +453,9 @@
 	}
 	XXXAN(vep->include_src);
 	if (vep->o_skip > 0) 
-		vep_emit_skip(vep, &vep->o_skip);
+		vep_emit_common(vep, &vep->o_skip, 1);
 	if (vep->o_verbatim > 0) 
-		vep_emit_verbatim(vep, &vep->o_verbatim);
+		vep_emit_common(vep, &vep->o_verbatim, 0);
 	/* XXX: what if it contains NUL bytes ?? */
 	p = vsb_data(vep->include_src);
 	l = vsb_len(vep->include_src);
@@ -863,8 +927,7 @@
 			INCOMPL();
 		}
 	}
-	vep->o_pending +=  p - vep->ver_p;
-	vep->ver_p = p;
+	vep_mark_pending(vep, p);
 }
 
 /*---------------------------------------------------------------------
@@ -944,9 +1007,11 @@
 	vep->magic = VEP_MAGIC;
 	vep->sp = sp;
 	vep->bytes = vfp_esi_bytes_uu;
+	vep->state = VEP_START;
 	vep->vsb = vsb_newauto();
-	vep->state = VEP_START;
 	AN(vep->vsb);
+	vep->crc = crc32(0L, Z_NULL, 0);
+	vep->crcp = crc32(0L, Z_NULL, 0);
 
 	sp->wrk->vep = vep;
 	(void)estimate;
@@ -985,14 +1050,12 @@
 	    (intmax_t)vep->o_skip, (intmax_t)vep->o_verbatim,
 	    (intmax_t)vep->o_total, (intmax_t)sp->obj->len, (intmax_t)l);
 	assert(l >= 0);
-	if (vep->o_skip)
-		vep_emit_skip(vep, &vep->o_skip);
-	if (vep->o_verbatim)
-		vep_emit_verbatim(vep, &vep->o_verbatim);
-	l = sp->obj->len - vep->o_total;
-	if (l)
-		vep_emit_verbatim(vep, &l);
-	vep->o_verbatim += l;
+	if (vep->o_pending)
+		vep_mark_verbatim(vep, vep->ver_p);
+	if (vep->o_skip > 0)
+		vep_emit_common(vep, &vep->o_skip, 1);
+	else if (vep->o_verbatim > 0)
+		vep_emit_common(vep, &vep->o_verbatim, 0);
 	vsb_finish(vep->vsb);
 	l = vsb_len(vep->vsb);
 	if (vep->state != VEP_NOTXML && l > 0) {




More information about the varnish-commit mailing list