[master] 438d765ef Rewrite the core of the gzip/gunzip code to use VSBs.
Poul-Henning Kamp
phk at FreeBSD.org
Mon Aug 24 12:30:10 UTC 2020
commit 438d765ef1ffb80e6adb59daa270bc317298cc86
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Aug 24 10:37:59 2020 +0000
Rewrite the core of the gzip/gunzip code to use VSBs.
diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h
index 2300288d4..cd21edb75 100644
--- a/bin/varnishtest/vtc.h
+++ b/bin/varnishtest/vtc.h
@@ -132,7 +132,7 @@ void stop_h2(struct http *hp);
void b64_settings(const struct http *hp, const char *s);
/* vtc_gzip.c */
-void vtc_gzip(const struct http *, const char *, char **, long *);
+void vtc_gzip(struct http *, const char *, char **, long *);
void vtc_gunzip(struct http *, char *, long *);
/* vtc_subr.c */
diff --git a/bin/varnishtest/vtc_gzip.c b/bin/varnishtest/vtc_gzip.c
index 2e56d41d5..9615efdfd 100644
--- a/bin/varnishtest/vtc_gzip.c
+++ b/bin/varnishtest/vtc_gzip.c
@@ -38,100 +38,149 @@
#include "vtc_http.h"
#include "vgz.h"
-#define OVERHEAD 64L
-
#ifdef VGZ_EXTENSIONS
static void
-vtc_report_gz_bits(const struct http *hp, z_stream *vz)
+vtc_report_gz_bits(struct vtclog *vl, const z_stream *vz)
{
- vtc_log(hp->vl, 4, "startbit = %ju %ju/%ju",
+ vtc_log(vl, 4, "startbit = %ju %ju/%ju",
(uintmax_t)vz->start_bit,
(uintmax_t)vz->start_bit >> 3, (uintmax_t)vz->start_bit & 7);
- vtc_log(hp->vl, 4, "lastbit = %ju %ju/%ju",
+ vtc_log(vl, 4, "lastbit = %ju %ju/%ju",
(uintmax_t)vz->last_bit,
(uintmax_t)vz->last_bit >> 3, (uintmax_t)vz->last_bit & 7);
- vtc_log(hp->vl, 4, "stopbit = %ju %ju/%ju",
+ vtc_log(vl, 4, "stopbit = %ju %ju/%ju",
(uintmax_t)vz->stop_bit,
(uintmax_t)vz->stop_bit >> 3, (uintmax_t)vz->stop_bit & 7);
}
#endif
-void
-vtc_gzip(const struct http *hp, const char *input, char **body, long *bodylen)
+static struct vsb *
+vtc_gzip_vsb(struct vtclog *vl, int fatal, int gzip_level, const struct vsb *vin, int *residual)
{
- unsigned l;
z_stream vz;
-#ifdef VGZ_EXTENSIONS
+ struct vsb *vout;
int i;
-#endif
+ char buf[BUFSIZ];
+ AN(residual);
memset(&vz, 0, sizeof vz);
+ vout = VSB_new_auto();
+ AN(vout);
- l = strlen(input);
- *body = calloc(1, l + OVERHEAD);
- AN(*body);
+ vz.next_in = (void*)VSB_data(vin);
+ vz.avail_in = VSB_len(vin);
- vz.next_in = TRUST_ME(input);
- vz.avail_in = l;
+ assert(Z_OK == deflateInit2(&vz,
+ gzip_level, Z_DEFLATED, 31, 9, Z_DEFAULT_STRATEGY));
+
+ do {
+ vz.next_out = (void*)buf;
+ vz.avail_out = sizeof buf;
+ i = deflate(&vz, Z_FINISH);
+ if (vz.avail_out != sizeof buf)
+ VSB_bcat(vout, buf, sizeof buf - vz.avail_out);
+ } while (i == Z_OK || i == Z_BUF_ERROR);
+ if (i != Z_STREAM_END)
+ vtc_log(vl, fatal,
+ "Gzip error = %d (%s) in:%jd out:%jd",
+ i, vz.msg, (intmax_t)vz.total_in, (intmax_t)vz.total_out);
+ AZ(VSB_finish(vout));
+#ifdef VGZ_EXTENSIONS
+ *residual = vz.stop_bit & 7;
+ vtc_report_gz_bits(vl, &vz);
+#else
+ *residual = 0;
+#endif
+ assert(Z_OK == deflateEnd(&vz));
+ return (vout);
+}
- vz.next_out = TRUST_ME(*body);
- vz.avail_out = l + OVERHEAD;
+void
+vtc_gzip(struct http *hp, const char *input, char **body, long *bodylen)
+{
+ struct vsb *vin, *vout;
+ int res;
+
+ vin = VSB_new_auto();
+ AN(vin);
+ VSB_bcat(vin, input, strlen(input));
+ AZ(VSB_finish(vin));
+ vout = vtc_gzip_vsb(hp->vl, hp->fatal, hp->gziplevel, vin, &res);
+ VSB_destroy(&vin);
- assert(Z_OK == deflateInit2(&vz,
- hp->gziplevel, Z_DEFLATED, 31, 9, Z_DEFAULT_STRATEGY));
- assert(Z_STREAM_END == deflate(&vz, Z_FINISH));
- *bodylen = vz.total_out;
#ifdef VGZ_EXTENSIONS
- i = vz.stop_bit & 7;
- if (hp->gzipresidual >= 0 && hp->gzipresidual != i)
+ if (hp->gzipresidual >= 0 && hp->gzipresidual != res)
vtc_log(hp->vl, hp->fatal,
"Wrong gzip residual got %d wanted %d",
- i, hp->gzipresidual);
- vtc_report_gz_bits(hp, &vz);
+ res, hp->gzipresidual);
#endif
- assert(Z_OK == deflateEnd(&vz));
+ *body = malloc(VSB_len(vout) + 1);
+ AN(*body);
+ memcpy(*body, VSB_data(vout), VSB_len(vout) + 1);
+ *bodylen = VSB_len(vout);
+ VSB_destroy(&vout);
+ vtc_log(hp->vl, 3, "new bodylen %ld", *bodylen);
+ vtc_dump(hp->vl, 4, "body", *body, *bodylen);
+ bprintf(hp->bodylen, "%ld", *bodylen);
}
-void
-vtc_gunzip(struct http *hp, char *body, long *bodylen)
+static struct vsb *
+vtc_gunzip_vsb(struct vtclog *vl, int fatal, const struct vsb *vin)
{
z_stream vz;
- char *p;
- unsigned l;
+ struct vsb *vout;
int i;
+ char buf[BUFSIZ];
memset(&vz, 0, sizeof vz);
+ vout = VSB_new_auto();
+ AN(vout);
+
+ vz.next_in = (void*)VSB_data(vin);
+ vz.avail_in = VSB_len(vin);
+
+ assert(Z_OK == inflateInit2(&vz, 31));
+
+ do {
+ vz.next_out = (void*)buf;
+ vz.avail_out = sizeof buf;
+ i = inflate(&vz, Z_FINISH);
+ if (vz.avail_out != sizeof buf)
+ VSB_bcat(vout, buf, sizeof buf - vz.avail_out);
+ } while (i == Z_OK || i == Z_BUF_ERROR);
+ if (i != Z_STREAM_END)
+ vtc_log(vl, fatal,
+ "Gunzip error = %d (%s) in:%jd out:%jd",
+ i, vz.msg, (intmax_t)vz.total_in, (intmax_t)vz.total_out);
+ AZ(VSB_finish(vout));
+#ifdef VGZ_EXTENSIONS
+ vtc_report_gz_bits(vl, &vz);
+#endif
+ assert(Z_OK == inflateEnd(&vz));
+ return (vout);
+}
+
+void
+vtc_gunzip(struct http *hp, char *body, long *bodylen)
+{
+ struct vsb *vin, *vout;
AN(body);
if (body[0] != (char)0x1f || body[1] != (char)0x8b)
vtc_log(hp->vl, hp->fatal,
"Gunzip error: body lacks gzip magic");
- vz.next_in = TRUST_ME(body);
- vz.avail_in = *bodylen;
-
- l = *bodylen * 10;
- p = calloc(1, l);
- AN(p);
- vz.next_out = TRUST_ME(p);
- vz.avail_out = l;
+ vin = VSB_new_auto();
+ AN(vin);
+ VSB_bcat(vin, body, *bodylen);
+ AZ(VSB_finish(vin));
+ vout = vtc_gunzip_vsb(hp->vl, hp->fatal, vin);
+ VSB_destroy(&vin);
- assert(Z_OK == inflateInit2(&vz, 31));
- i = inflate(&vz, Z_FINISH);
- assert(vz.total_out < l);
- *bodylen = vz.total_out;
- memcpy(body, p, *bodylen);
- free(p);
+ memcpy(body, VSB_data(vout), VSB_len(vout) + 1);
+ *bodylen = VSB_len(vout);
+ VSB_destroy(&vout);
vtc_log(hp->vl, 3, "new bodylen %ld", *bodylen);
vtc_dump(hp->vl, 4, "body", body, *bodylen);
bprintf(hp->bodylen, "%ld", *bodylen);
-#ifdef VGZ_EXTENSIONS
- vtc_report_gz_bits(hp, &vz);
-#endif
- if (i != Z_STREAM_END)
- vtc_log(hp->vl, hp->fatal,
- "Gunzip error = %d (%s) in:%jd out:%jd",
- i, vz.msg, (intmax_t)vz.total_in, (intmax_t)vz.total_out);
- assert(Z_OK == inflateEnd(&vz));
- body[*bodylen] = '\0';
}
More information about the varnish-commit
mailing list