[master] c394dfb Be able to detect parse error during processing of backend Vary headers, and do 503 on parse error.

Martin Blix Grydeland martin at varnish-cache.org
Tue Mar 19 15:43:19 CET 2013


commit c394dfb760191171a2a1e2eb0b630077b40c079c
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Mon Mar 18 11:55:54 2013 +0100

    Be able to detect parse error during processing of backend Vary
    headers, and do 503 on parse error.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 6be2c73..a63c36e 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -1003,7 +1003,7 @@ void RES_BuildHttp(struct req *);
 void RES_WriteObj(struct req *);
 
 /* cache_vary.c */
-struct vsb *VRY_Create(struct req *sp, const struct http *hp);
+int VRY_Create(struct req *req, const struct http *hp, struct vsb **psb);
 int VRY_Match(struct req *, const uint8_t *vary);
 void VRY_Validate(const uint8_t *vary);
 void VRY_Prep(struct req *);
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 49a6732..e1fd343 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -572,12 +572,24 @@ cnt_fetchbody(struct worker *wrk, struct req *req)
 
 	/* Create Vary instructions */
 	if (req->objcore->objhead != NULL) {
-		vary = VRY_Create(req, bo->beresp);
-		if (vary != NULL) {
-			varyl = VSB_len(vary);
-			assert(varyl > 0);
+		varyl = VRY_Create(req, bo->beresp, &vary);
+		if (varyl > 0) {
+			AN(vary);
+			assert(varyl == VSB_len(vary));
 			l += varyl;
-		}
+		} else if (varyl < 0) {
+			/* Vary parse error */
+			AZ(vary);
+			req->err_code = 503;
+			req->req_step = R_STP_ERROR;
+			AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
+			req->objcore = NULL;
+			VDI_CloseFd(&bo->vbc);
+			VBO_DerefBusyObj(wrk, &req->busyobj);
+			return (REQ_FSM_MORE);
+		} else
+			/* No vary */
+			AZ(vary);
 	}
 
 	/*
diff --git a/bin/varnishd/cache/cache_vary.c b/bin/varnishd/cache/cache_vary.c
index d4319b2..f35b2ae 100644
--- a/bin/varnishd/cache/cache_vary.c
+++ b/bin/varnishd/cache/cache_vary.c
@@ -61,16 +61,29 @@
 #include "vct.h"
 #include "vend.h"
 
-struct vsb *
-VRY_Create(struct req *req, const struct http *hp)
+/**********************************************************************
+ * Create a Vary matching string from a Vary header
+ *
+ * Return value:
+ * <0: Parse error
+ *  0: No Vary header on object
+ * >0: Length of Vary matching string in *psb
+ */
+
+int
+VRY_Create(struct req *req, const struct http *hp, struct vsb **psb)
 {
 	char *v, *p, *q, *h, *e;
 	struct vsb *sb, *sbh;
 	unsigned l;
+	int error = 0;
+
+	AN(psb);
+	AZ(*psb);
 
 	/* No Vary: header, no worries */
 	if (!http_GetHdr(hp, H_Vary, &v))
-		return (NULL);
+		return (0);
 
 	/* For vary matching string */
 	sb = VSB_new_auto();
@@ -125,12 +138,20 @@ VRY_Create(struct req *req, const struct http *hp)
 		xxxassert(*q == ',');
 		p = q;
 	}
+
+	if (error) {
+		VSB_delete(sbh);
+		VSB_delete(sb);
+		return (-1);
+	}
+
 	/* Terminate vary matching string */
 	VSB_printf(sb, "%c%c%c", 0xff, 0xff, 0);
 
 	VSB_delete(sbh);
 	AZ(VSB_finish(sb));
-	return(sb);
+	*psb = sb;
+	return (VSB_len(sb));
 }
 
 /*



More information about the varnish-commit mailing list