[PATCH 4/8] Be able to detect parse error during processing of backend Vary headers, and do 503 on parse error.
Martin Blix Grydeland
martin at varnish-software.com
Mon Mar 18 17:57:25 CET 2013
---
bin/varnishd/cache/cache.h | 2 +-
bin/varnishd/cache/cache_req_fsm.c | 22 ++++++++++++++----
bin/varnishd/cache/cache_vary.c | 45 ++++++++++++++++++++++++++----------
3 files changed, 51 insertions(+), 18 deletions(-)
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 af2fa21..19c9eaa 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..34f1891 100644
--- a/bin/varnishd/cache/cache_vary.c
+++ b/bin/varnishd/cache/cache_vary.c
@@ -61,20 +61,33 @@
#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;
+ struct vsb *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();
- AN(sb);
+ *psb = VSB_new_auto();
+ AN(*psb);
/* For header matching strings */
sbh = VSB_new_auto();
@@ -112,11 +125,11 @@ VRY_Create(struct req *req, const struct http *hp)
e = h;
l = 0xffff;
}
- VSB_printf(sb, "%c%c", (int)(l >> 8), (int)(l & 0xff));
+ VSB_printf(*psb, "%c%c", (int)(l >> 8), (int)(l & 0xff));
/* Append to vary matching string */
- VSB_bcat(sb, VSB_data(sbh), VSB_len(sbh));
+ VSB_bcat(*psb, VSB_data(sbh), VSB_len(sbh));
if (e != h)
- VSB_bcat(sb, h, e - h);
+ VSB_bcat(*psb, h, e - h);
while (vct_issp(*q))
q++;
@@ -125,12 +138,20 @@ VRY_Create(struct req *req, const struct http *hp)
xxxassert(*q == ',');
p = q;
}
+
+ if (error) {
+ VSB_delete(sbh);
+ VSB_delete(*psb);
+ *psb = NULL;
+ return (-1);
+ }
+
/* Terminate vary matching string */
- VSB_printf(sb, "%c%c%c", 0xff, 0xff, 0);
+ VSB_printf(*psb, "%c%c%c", 0xff, 0xff, 0);
VSB_delete(sbh);
- AZ(VSB_finish(sb));
- return(sb);
+ AZ(VSB_finish(*psb));
+ return (VSB_len(*psb));
}
/*
--
1.7.10.4
More information about the varnish-dev
mailing list