[master] a2f873f Register buffer allocation failuers on vgz's and make failure to clean those up non-fatal.
Poul-Henning Kamp
phk at varnish-cache.org
Tue Oct 25 11:45:10 CEST 2011
commit a2f873f20f4ee3b05ada950b168a25523550c99c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Oct 25 09:44:39 2011 +0000
Register buffer allocation failuers on vgz's and make failure
to clean those up non-fatal.
Fixes #1036
diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c
index 541d30e..08d298e 100644
--- a/bin/varnishd/cache_gzip.c
+++ b/bin/varnishd/cache_gzip.c
@@ -83,6 +83,7 @@ struct vgz {
const char *id;
struct ws *tmp;
char *tmp_snapshot;
+ const char *error;
struct storage *obuf;
@@ -261,8 +262,10 @@ VGZ_ObufStorage(struct worker *w, struct vgz *vg)
struct storage *st;
st = FetchStorage(w, 0);
- if (st == NULL)
+ if (st == NULL) {
+ vg->error = "Could not get ObufStorage";
return (-1);
+ }
vg->obuf = st;
VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len);
@@ -407,6 +410,7 @@ void
VGZ_Destroy(struct vgz **vgp)
{
struct vgz *vg;
+ const char *err;
vg = *vgp;
CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
@@ -419,12 +423,13 @@ VGZ_Destroy(struct vgz **vgp)
(intmax_t)vg->vz.start_bit,
(intmax_t)vg->vz.last_bit,
(intmax_t)vg->vz.stop_bit);
+ err = vg->error;
if (vg->tmp != NULL)
WS_Reset(vg->tmp, vg->tmp_snapshot);
if (vg->dir == VGZ_GZ)
- AZ(deflateEnd(&vg->vz));
+ assert(deflateEnd(&vg->vz) == 0 || err != NULL);
else
- AZ(inflateEnd(&vg->vz));
+ assert(inflateEnd(&vg->vz) == 0 || err != NULL);
FREE_OBJ(vg);
}
@@ -564,18 +569,20 @@ vfp_gzip_end(struct worker *w)
int i;
vg = w->vgz_rx;
- w->vgz_rx = NULL;
CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
- do {
- VGZ_Ibuf(vg, "", 0);
- if (VGZ_ObufStorage(w, vg))
- return (-1);
- i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH);
+ w->vgz_rx = NULL;
+ if (vg->error == NULL) {
+ do {
+ VGZ_Ibuf(vg, "", 0);
+ if (VGZ_ObufStorage(w, vg))
+ return (-1);
+ i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH);
w->fetch_obj->len += dl;
- } while (i != Z_STREAM_END);
- if (w->do_stream)
- RES_StreamPoll(w);
- VGZ_UpdateObj(vg, w->fetch_obj);
+ } while (i != Z_STREAM_END);
+ if (w->do_stream)
+ RES_StreamPoll(w);
+ VGZ_UpdateObj(vg, w->fetch_obj);
+ }
VGZ_Destroy(&vg);
return (0);
}
@@ -619,6 +626,7 @@ vfp_testgzip_bytes(struct worker *w, struct http_conn *htc, ssize_t bytes)
st = FetchStorage(w, 0);
if (st == NULL) {
htc->error = "Could not get storage";
+ vg->error = htc->error;
return (-1);
}
l = st->space - st->len;
diff --git a/bin/varnishtest/tests/r01036.vtc b/bin/varnishtest/tests/r01036.vtc
new file mode 100644
index 0000000..8fb7600
--- /dev/null
+++ b/bin/varnishtest/tests/r01036.vtc
@@ -0,0 +1,22 @@
+varnishtest "Test case for #1036"
+
+server s1 {
+ rxreq
+ # Send a bodylen of 1,5M, which will exceed cache space of 1M
+ non-fatal
+ txresp -bodylen 1572864
+} -start
+
+varnish v1 -arg "-smalloc,1M" -arg "-pgzip_level=0" -vcl+backend {
+ sub vcl_fetch {
+ set beresp.do_gzip = true;
+ }
+} -start
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == "503"
+} -run
+
+
More information about the varnish-commit
mailing list