Handle workspace allocation errors in VEP_Init()

Turn assertion into VFP error

The vtc is based upon r02645.vtc and reliably reproduces the panic
without the patch by sweeping through possible amounts of free workspace
ranging from 4 to 400 bytes.

Fixes #3253
parent ed36b638
......@@ -165,8 +165,13 @@ vfp_esi_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
if (vef == NULL)
return (VFP_ERROR);
vc->obj_flags |= OF_GZIPED | OF_CHGCE | OF_ESIPROC;
vef->vgz = VGZ_NewGzip(vc->wrk->vsl, "G F E");
vef->vep = VEP_Init(vc, vc->req, vfp_vep_callback, vef);
if (vef->vep == NULL) {
FREE_OBJ(vef);
return (VFP_ERROR);
}
vef->vgz = VGZ_NewGzip(vc->wrk->vsl, "G F E");
vef->ibuf_sz = cache_param->gzip_buffer;
vef->ibuf = calloc(1L, vef->ibuf_sz);
if (vef->ibuf == NULL)
......@@ -232,6 +237,7 @@ static enum vfp_status v_matchproto_(vfp_init_f)
vfp_esi_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
{
struct vef_priv *vef;
struct vep_state *vep;
CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vc->req, HTTP_MAGIC);
......@@ -240,11 +246,14 @@ vfp_esi_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
"Attempted ESI on partial (206) response");
return (VFP_ERROR);
}
vep = VEP_Init(vc, vc->req, NULL, NULL);
if (vep == NULL)
return (VFP_ERROR);
ALLOC_OBJ(vef, VEF_MAGIC);
if (vef == NULL)
return (VFP_ERROR);
vc->obj_flags |= OF_ESIPROC;
vef->vep = VEP_Init(vc, vc->req, NULL, NULL);
vef->vep = vep;
vfe->priv1 = vef;
return (VFP_OK);
}
......
......@@ -1042,7 +1042,11 @@ VEP_Init(struct vfp_ctx *vc, const struct http *req, vep_callback_t *cb,
CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
CHECK_OBJ_NOTNULL(req, HTTP_MAGIC);
vep = WS_Alloc(vc->resp->ws, sizeof *vep);
AN(vep);
if (vep == NULL) {
VSLb(vc->wrk->vsl, SLT_VCL_Error,
"VEP_Init() workspace overflow");
return (NULL);
}
INIT_OBJ(vep, VEP_MAGIC);
vep->url = req->hd[HTTP_HDR_URL].b;
......
varnishtest "ESI: sweep through tight backend workspace conditions"
server s1 -repeat 100 {
rxreq
txresp -gzipbody "<html>"
} -start
varnish v1 -vcl+backend {
import vtc;
import std;
sub vcl_recv {
return (pass);
}
sub vcl_backend_response {
vtc.workspace_alloc(backend, -4 *
(std.integer(bereq.xid, 1002) - 1000) / 2);
set beresp.do_esi = true;
}
} -start
client c1 -repeat 100 {
txreq -url "/"
# some responses will fail (503), some won't. All we care
# about here is the fact that we don't panic
rxresp
} -run
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment