r2169 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Wed Oct 24 21:38:43 CEST 2007


Author: phk
Date: 2007-10-24 21:38:43 +0200 (Wed, 24 Oct 2007)
New Revision: 2169

Modified:
   trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c
Log:
Add attribute parsing


Modified: trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c	2007-10-24 18:38:17 UTC (rev 2168)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c	2007-10-24 19:38:43 UTC (rev 2169)
@@ -41,6 +41,7 @@
  */
 
 #include <stdio.h>
+#include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -75,10 +76,63 @@
 };
 
 /*--------------------------------------------------------------------
+ * Report a parsing error
+ */
+
+static void
+esi_error(const struct esi_work *ew, const char *p, int i, const char *err)
+{
+	int ellipsis = 0;
+	char buf[256], *q;
+	txt t;
+
+	if (i == 0) 
+		i = p - ((char *)ew->st->ptr + ew->st->len);
+	if (i > 20) {
+		i = 20;
+		ellipsis = 1;
+	}
+	q = buf;
+	q += sprintf(buf, "at %zd: %s \"",
+	    ew->off + (p - (char*)ew->st->ptr), err);
+	while (i > 0) {
+		if (*p >= ' ' && *p <= '~') {
+			*q++ = *p;
+		} else if (*p == '\n') {
+			*q++ = '\\';
+			*q++ = 'n';
+		} else if (*p == '\r') {
+			*q++ = '\\';
+			*q++ = 'r';
+		} else if (*p == '\t') {
+			*q++ = '\\';
+			*q++ = 't';
+		} else {
+			/* XXX: use %%%02x instead ? */
+			q += sprintf(q, "\\x%02x", *p);
+		}
+		p++;
+		i--;
+	}
+	if (ellipsis) {
+		*q++ = '[';
+		*q++ = '.';
+		*q++ = '.';
+		*q++ = '.';
+		*q++ = ']';
+	}
+	*q++ = '"';
+	*q++ = '\0';
+	t.b = buf;
+	t.e = q;
+	WSPR(ew->sp, SLT_ESI_xmlerror, t);
+}
+
+/*--------------------------------------------------------------------
  * Add ESI bit to object
  */
 
-static void
+static struct esi_bit *
 esi_addbit(struct esi_work *ew)
 {
 
@@ -99,6 +153,7 @@
 	ew->eb->verbatim = ew->dst;
 	sprintf(ew->eb->chunk_length, "%x\r\n", Tlen(ew->dst));
 	VSL(SLT_Debug, ew->sp->fd, "AddBit: %.*s", Tlen(ew->dst), ew->dst.b);
+	return(ew->eb);
 }
 
 
@@ -116,69 +171,101 @@
 }
 
 /*--------------------------------------------------------------------
- * Add one piece to the output, either verbatim or include
+ * Tease the next attribute and value out of an XML element.
+ *
+ * XXX: is the syntax correct ?
  */
 
-static void
-esi_addinclude(struct esi_work *ew, txt t)
+static int
+esi_attrib(const struct esi_work *ew, txt *in, txt *attrib, txt *val)
 {
 
-	VSL(SLT_Debug, 0, "Incl \"%.*s\"", t.e - t.b, t.b);
-	esi_addbit(ew);
-	ew->eb->include = t;
+	/* Skip leading blanks */
+	while(in->b < in->e && isspace(*in->b))
+		in->b++;
+
+	/* Nothing found */
+	if (in->b >= in->e)
+		return (0);
+
+	if (!isalpha(*in->b)) {
+		/* XXX error */
+		esi_error(ew, in->b, 1, "XML 1.0 Illegal attribute character");
+		return (-1);
+	}
+
+	/* Attribute name until '=' or space */
+	*attrib = *in;
+	while(in->b < in->e && *in->b != '=' && !isspace(*in->b)) {
+		if (!isalnum(*in->b)) {
+			esi_error(ew, attrib->b, 1 + (in->b - attrib->b),
+			    "XML 1.0 Illegal attribute character");
+			return (-1);
+		}
+		in->b++;
+	}
+	attrib->e = in->b;
+
+	if (in->b >= in->e || isspace(*in->b)) {
+		/* Attribute without value */
+		val->b = val->e = in->b;
+		return (1);
+	}
+
+	/* skip '=' */
+	in->b++;
+
+	/* Value, if any ? */
+	*val = *in;
+	if (in->b >= in->e) 
+		return (1);
+
+	if (*in->b == '"') {
+		/* Skip quote */
+		in->b++;
+		val->b++;
+
+		/* Anything goes, until next quote */
+		while(in->b < in->e && *in->b != '"')
+			in->b++;
+		val->e = in->b;
+
+		if (in->b >= in->e) {
+			esi_error(ew, val->b, in->e - val->b,
+			    "XML 1.0 missing ending quote");
+			return (-1);
+		}
+
+		/* Skip quote */
+		in->b++;
+	} else {
+		/* Anything until whitespace */
+		while(in->b < in->e && !isspace(*in->b))
+			in->b++;
+		val->e = in->b;
+	}
+	return (1);
 }
 
 /*--------------------------------------------------------------------
- * Report a parsing error
+ * Add one piece to the output, either verbatim or include
  */
 
 static void
-esi_error(const struct esi_work *ew, const char *p, int i, const char *err)
+esi_addinclude(struct esi_work *ew, txt t)
 {
-	int ellipsis = 0;
-	char buf[256], *q;
-	txt t;
+	struct esi_bit *eb;
+	txt tag;
+	txt cont;
 
-	if (i == 0) 
-		i = p - ((char *)ew->st->ptr + ew->st->len);
-	if (i > 20) {
-		i = 20;
-		ellipsis = 1;
+	eb = esi_addbit(ew);
+	while (esi_attrib(ew, &t, &tag, &cont) == 1) {
+		VSL(SLT_Debug, 0, "<%.*s> -> <%.*s>",
+		    tag.e - tag.b, tag.b,
+		    cont.e - cont.b, cont.b);
 	}
-	q = buf;
-	q += sprintf(buf, "at %zd: %s \"",
-	    ew->off + (p - (char*)ew->st->ptr), err);
-	while (i > 0) {
-		if (*p >= ' ' && *p <= '~') {
-			*q++ = *p;
-		} else if (*p == '\n') {
-			*q++ = '\\';
-			*q++ = 'n';
-		} else if (*p == '\r') {
-			*q++ = '\\';
-			*q++ = 'r';
-		} else if (*p == '\t') {
-			*q++ = '\\';
-			*q++ = 't';
-		} else {
-			/* XXX: use %%%02x instead ? */
-			q += sprintf(q, "\\x%02x", *p);
-		}
-		p++;
-		i--;
-	}
-	if (ellipsis) {
-		*q++ = '[';
-		*q++ = '.';
-		*q++ = '.';
-		*q++ = '.';
-		*q++ = ']';
-	}
-	*q++ = '"';
-	*q++ = '\0';
-	t.b = buf;
-	t.e = q;
-	WSPR(ew->sp, SLT_ESI_xmlerror, t);
+	eb->include = t;
+	VSL(SLT_Debug, 0, "Incl \"%.*s\"", t.e - t.b, t.b);
 }
 
 /*--------------------------------------------------------------------
@@ -366,12 +453,14 @@
 
 			if (celem == 0) {
 				o.b = r + 11;
-				o.e = q;
-				esi_addinclude(ew, o);
 				if (q[-1] != '/') {
 					esi_error(ew, p, 1 + q - p,
 					    "ESI 1.0 wants emtpy esi:include");
+					o.e = q;
+				} else {
+					o.e = q - 1;
 				}
+				esi_addinclude(ew, o);
 				ew->dst.b = q + 1;
 				ew->dst.e = q + 1;
 			} else {




More information about the varnish-commit mailing list