>From 4b7f85d98c29fa016ddedb9834b03681dfd8c227 Mon Sep 17 00:00:00 2001
From: Nils Goroll <[email protected]>
Date: Wed, 17 Feb 2016 15:06:02 +0100
Subject: [PATCH] Error handling for V1F_Setup_Fetch
---
bin/varnishd/cache/cache_backend.c | 3 +--
bin/varnishd/cache/cache_fetch.c | 10 ++++++++--
bin/varnishd/cache/cache_req_fsm.c | 8 +++++++-
bin/varnishd/http1/cache_http1.h | 2 +-
bin/varnishd/http1/cache_http1_fsm.c | 3 ++-
bin/varnishd/http1/cache_http1_vfp.c | 12 ++++++++----
6 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 5879518..8b11386 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -247,8 +247,7 @@ vbe_dir_getbody(const struct director *d, struct worker *wrk,
CHECK_OBJ_NOTNULL(bo->vfc, VFP_CTX_MAGIC);
CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
- V1F_Setup_Fetch(bo->vfc, bo->htc);
- return (0);
+ return (V1F_Setup_Fetch(bo->vfc, bo->htc));
}
static const struct suckaddr * __match_proto__(vdi_getip_f)
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 2f44dcd..0a240bd 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -652,8 +652,14 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
http_GetHdr(bo->beresp, H_ETag, &p)))
ObjSetFlag(bo->wrk, bo->fetch_objcore, OF_IMSCAND, 1);
- if (bo->htc->body_status != BS_NONE)
- AZ(VDI_GetBody(bo->wrk, bo));
+ if (bo->htc->body_status != BS_NONE &&
+ VDI_GetBody(bo->wrk, bo) != 0) {
+ (void)VFP_Error(bo->vfc,
+ "GetBody failed - backend_workspace overflow?");
+ bo->htc->doclose = SC_OVERLOAD;
+ VDI_Finish(bo->wrk, bo);
+ return (F_STP_ERROR);
+ }
assert(bo->fetch_objcore->boc->refcount >= 1);
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 25f4e33..733b21d 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -688,9 +688,15 @@ cnt_recv(struct worker *wrk, struct req *req)
VFP_Setup(req->htc->vfc);
req->htc->vfc->http = req->http;
req->htc->vfc->wrk = wrk;
- if (req->transport->req_body != NULL)
+ if (req->transport->req_body != NULL) {
req->transport->req_body(req);
+ if (req->req_body_status == REQ_BODY_FAIL) {
+ req->doclose = SC_OVERLOAD;
+ return (REQ_FSM_DONE);
+ }
+ }
+
VCL_recv_method(req->vcl, wrk, req, NULL, NULL);
/* Attempts to cache req.body may fail */
diff --git a/bin/varnishd/http1/cache_http1.h b/bin/varnishd/http1/cache_http1.h
index 07f2d63..bd74ed4 100644
--- a/bin/varnishd/http1/cache_http1.h
+++ b/bin/varnishd/http1/cache_http1.h
@@ -31,7 +31,7 @@
int V1F_SendReq(struct worker *, struct busyobj *, uint64_t *ctr,
int onlycached);
int V1F_FetchRespHdr(struct busyobj *);
-void V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc);
+int V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc);
/* cache_http1_fsm.c [HTTP1] */
void HTTP1_Session(struct worker *, struct req *);
diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c
index f30c3b0..073684e 100644
--- a/bin/varnishd/http1/cache_http1_fsm.c
+++ b/bin/varnishd/http1/cache_http1_fsm.c
@@ -146,7 +146,8 @@ http1_req_body(struct req *req)
case BS_EOF:
case BS_LENGTH:
case BS_CHUNKED:
- V1F_Setup_Fetch(req->htc->vfc, req->htc);
+ if (V1F_Setup_Fetch(req->htc->vfc, req->htc) != 0)
+ req->req_body_status = REQ_BODY_FAIL;
break;
default:
break;
diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c
index 1c11384..9f6e1a3 100644
--- a/bin/varnishd/http1/cache_http1_vfp.c
+++ b/bin/varnishd/http1/cache_http1_vfp.c
@@ -260,7 +260,7 @@ static const struct vfp v1f_eof = {
/*--------------------------------------------------------------------
*/
-void
+int
V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc)
{
struct vfp_entry *vfe;
@@ -272,19 +272,22 @@ V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc)
case BS_EOF:
assert(htc->content_length == -1);
vfe = VFP_Push(vfc, &v1f_eof, 0);
- XXXAN(vfe);
+ if (vfe == NULL)
+ return ENOSPC;
vfe->priv2 = 0;
break;
case BS_LENGTH:
assert(htc->content_length > 0);
vfe = VFP_Push(vfc, &v1f_straight, 0);
- XXXAN(vfe);
+ if (vfe == NULL)
+ return ENOSPC;
vfe->priv2 = htc->content_length;
break;
case BS_CHUNKED:
assert(htc->content_length == -1);
vfe = VFP_Push(vfc, &v1f_chunked, 0);
- XXXAN(vfe);
+ if (vfe == NULL)
+ return ENOSPC;
vfe->priv2 = -1;
break;
default:
@@ -292,4 +295,5 @@ V1F_Setup_Fetch(struct vfp_ctx *vfc, struct http_conn *htc)
break;
}
vfe->priv1 = htc;
+ return 0;
}
--
2.1.4
_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev