Example #1
0
static int
vfp_esi_bytes_gg(const struct busyobj *bo, struct vef_priv *vef,
    struct http_conn *htc, size_t bytes)
{
	ssize_t wl;
	size_t dl;
	const void *dp;
	enum vgzret_e vr;

	CHECK_OBJ_NOTNULL(vef, VEF_MAGIC);
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);

	while (bytes > 0) {
		wl = vef_read(htc, vef->ibuf2, vef->ibuf2_sz, bytes);
		if (wl <= 0)
			return (wl);
		bytes -= wl;

		VGZ_Ibuf(bo->vgz_rx, vef->ibuf2, wl);
		do {
			wl = vef->ibuf_sz - (vef->ibuf_i - vef->ibuf);
			VGZ_Obuf(bo->vgz_rx, vef->ibuf_i, wl);
			vr = VGZ_Gunzip(bo->vgz_rx, &dp, &dl);
			if (vr < VGZ_OK)
				return (-1);
			if (dl > 0 && vfp_vep_inject(bo, vef, dl))
				return (-1);
		} while (!VGZ_IbufEmpty(bo->vgz_rx));
	}
	return (1);
}
Example #2
0
int
VGZ_WrwInit(struct vgz *vg)
{

	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);

	if (vgz_getmbuf(vg))
		return (-1);

	VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
	return (0);
}
Example #3
0
int
VGZ_ObufStorage(struct busyobj *bo, struct vgz *vg)
{
	struct storage *st;

	st = VFP_GetStorage(bo, 0);
	if (st == NULL)
		return (-1);

	VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len);

	return (0);
}
Example #4
0
int
VGZ_ObufStorage(struct busyobj *bo, struct vgz *vg)
{
	struct storage *st;

	st = FetchStorage(bo, 0);
	if (st == NULL)
		return (-1);

	vg->st_obuf = st;
	VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len);

	return (0);
}
Example #5
0
static int
vfp_esi_bytes_gg(struct worker *wrk, struct http_conn *htc, size_t bytes)
{
	ssize_t wl;
	char ibuf[cache_param->gzip_stack_buffer];
	char ibuf2[cache_param->gzip_stack_buffer];
	struct vef_priv *vef;
	size_t dl;
	const void *dp;
	int i;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC);
	vef = wrk->busyobj->vef_priv;
	CHECK_OBJ_NOTNULL(vef, VEF_MAGIC);
	assert(sizeof ibuf >= 1024);
	ibuf2[0] = 0; /* For Flexelint */

	while (bytes > 0) {
		wl = vef_read(wrk, htc, ibuf, sizeof ibuf, bytes);
		if (wl <= 0)
			return (wl);
		bytes -= wl;

		vef->bufp = ibuf;
		VGZ_Ibuf(wrk->busyobj->vgz_rx, ibuf, wl);
		do {
			VGZ_Obuf(wrk->busyobj->vgz_rx, ibuf2, sizeof ibuf2);
			i = VGZ_Gunzip(wrk->busyobj->vgz_rx, &dp, &dl);
			/* XXX: check i */
			assert(i >= VGZ_OK);
			vef->bufp = ibuf2;
			if (dl > 0)
				VEP_Parse(wrk, ibuf2, dl);
			if (vef->error) {
				errno = vef->error;
				return (-1);
			}
			if (vef->bufp < ibuf2 + dl) {
				dl = (ibuf2 + dl) - vef->bufp;
				assert(dl + vef->npend < sizeof vef->pending);
				memmove(vef->pending + vef->npend,
				    vef->bufp, dl);
				vef->npend += dl;
			}
		} while (!VGZ_IbufEmpty(wrk->busyobj->vgz_rx));
	}
	return (1);
}
Example #6
0
static ssize_t
vfp_vep_callback(struct vfp_ctx *vc, void *priv, ssize_t l, enum vgz_flag flg)
{
	struct vef_priv *vef;
	ssize_t dl;
	const void *dp;
	uint8_t *ptr;
	int i;

	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
	CAST_OBJ_NOTNULL(vef, priv, VEF_MAGIC);
	assert(l >= 0);

	if (vef->error) {
		vef->tot += l;
		return (vef->tot);
	}

	/*
	 * l == 0 is valid when 'flg' calls for action, but in the
	 * normal case we can just ignore a l==0 request.
	 * (It would cause Z_BUF_ERROR anyway)
	 */
	if (l == 0 && flg == VGZ_NORMAL)
		return (vef->tot);

	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
	VGZ_Ibuf(vef->vgz, vef->ibuf_o, l);
	do {
		dl = 0;
		if (VFP_GetStorage(vc, &dl, &ptr) != VFP_OK) {
			vef->error = ENOMEM;
			vef->tot += l;
			return (vef->tot);
		}
		VGZ_Obuf(vef->vgz, ptr, dl);
		i = VGZ_Gzip(vef->vgz, &dp, &dl, flg);
		VGZ_UpdateObj(vc, vef->vgz, VUA_UPDATE);
		if (dl > 0) {
			vef->tot += dl;
			VFP_Extend(vc, dl);
		}
	} while (i != VGZ_ERROR &&
	    (!VGZ_IbufEmpty(vef->vgz) || VGZ_ObufFull(vef->vgz)));
	assert(i == VGZ_ERROR || VGZ_IbufEmpty(vef->vgz));
	vef->ibuf_o += l;
	return (vef->tot);
}
vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes)
{
	ssize_t w;
	char ibuf[params->gzip_stack_buffer];
	char ibuf2[params->gzip_stack_buffer];
	struct vef_priv *vef;
	size_t dl;
	const void *dp;
	int i;

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	vef = sp->wrk->vef_priv;
	CHECK_OBJ_NOTNULL(vef, VEF_MAGIC);
	assert(sizeof ibuf >= 1024);
	ibuf2[0] = 0; /* For Flexelint */

	while (bytes > 0) {
		w = vef_read(htc, ibuf, sizeof ibuf, bytes);
		if (w <= 0)
			return (w);
		bytes -= w;

		vef->bufp = ibuf;
		VGZ_Ibuf(sp->wrk->vgz_rx, ibuf, w);
		do {
			VGZ_Obuf(sp->wrk->vgz_rx, ibuf2, sizeof ibuf2);
			i = VGZ_Gunzip(sp->wrk->vgz_rx, &dp, &dl);
			/* XXX: check i */
			assert(i >= VGZ_OK);
			vef->bufp = ibuf2;
			if (dl > 0)
				VEP_parse(sp, ibuf2, dl);
			if (vef->error) {
				errno = vef->error;
				return (-1);
			}
			if (vef->bufp < ibuf2 + dl) {
				dl = (ibuf2 + dl) - vef->bufp;
				assert(dl + vef->npend < sizeof vef->pending);
				memmove(vef->pending + vef->npend,
				    vef->bufp, dl);
				vef->npend += dl;
			}
		} while (!VGZ_IbufEmpty(sp->wrk->vgz_rx));
	}
	return (1);
}
Example #8
0
vfp_gzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
    ssize_t *lp)
{
	ssize_t l;
	struct vgz *vg;
	enum vgzret_e vr = VGZ_ERROR;
	const void *dp;
	ssize_t dl;
	enum vfp_status vp = VFP_ERROR;

	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
	AN(p);
	AN(lp);
	l = *lp;
	*lp = 0;
	VGZ_Obuf(vg, p, l);
	do {
		if (VGZ_IbufEmpty(vg)) {
			l = vg->m_sz;
			vp = VFP_Suck(vc, vg->m_buf, &l);
			if (vp == VFP_ERROR)
				break;
			if (vp == VFP_END)
				vg->flag = VGZ_FINISH;
			VGZ_Ibuf(vg, vg->m_buf, l);
		}
		if (!VGZ_IbufEmpty(vg) || vg->flag == VGZ_FINISH) {
			vr = VGZ_Gzip(vg, &dp, &dl, vg->flag);
			if (vr < VGZ_OK)
				return (VFP_Error(vc, "Gzip failed"));
			if (dl > 0) {
				VGZ_UpdateObj(vc, vg, VUA_UPDATE);
				*lp = dl;
				assert(dp == p);
				return (VFP_OK);
			}
		}
		AN(VGZ_IbufEmpty(vg));
	} while (vg->flag != VGZ_FINISH);

	if (vr != VGZ_END)
		return (VFP_Error(vc, "Gzip failed"));
	VGZ_UpdateObj(vc, vg, VUA_END_GZIP);
	return (VFP_END);
}
Example #9
0
void
VGZ_WrwFlush(struct req *req, struct vgz *vg)
{
	struct worker *wrk;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	wrk = req->wrk;
	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);

	if (vg->m_len ==  0)
		return;

	(void)VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len);
	vg->m_len = 0;
	VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
}
Example #10
0
vfp_gunzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
    ssize_t *lp)
{
	ssize_t l;
	struct vgz *vg;
	enum vgzret_e vr = VGZ_ERROR;
	const void *dp;
	ssize_t dl;
	enum vfp_status vp = VFP_OK;

	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
	AN(p);
	AN(lp);
	l = *lp;
	*lp = 0;
	VGZ_Obuf(vg, p, l);
	do {
		if (VGZ_IbufEmpty(vg)) {
			l = vg->m_sz;
			vp = VFP_Suck(vc, vg->m_buf, &l);
			if (vp == VFP_ERROR)
				return (vp);
			VGZ_Ibuf(vg, vg->m_buf, l);
		}
		if (!VGZ_IbufEmpty(vg) || vp == VFP_END) {
			vr = VGZ_Gunzip(vg, &dp, &dl);
			if (vr == VGZ_END && !VGZ_IbufEmpty(vg))
				return(VFP_Error(vc, "Junk after gzip data"));
			if (vr < VGZ_OK)
				return (VFP_Error(vc,
				    "Invalid Gzip data: %s", vgz_msg(vg)));
			if (dl > 0) {
				*lp = dl;
				assert(dp == p);
				return (VFP_OK);
			}
		}
		AN(VGZ_IbufEmpty(vg));
	} while (vp == VFP_OK);
	if (vr != VGZ_END)
		return(VFP_Error(vc, "Gunzip error at the very end"));
	return (vp);
}
Example #11
0
static ssize_t
vfp_vep_callback(struct busyobj *bo, void *priv, ssize_t l, enum vgz_flag flg)
{
    struct vef_priv *vef;
    size_t dl;
    const void *dp;
    struct storage *st;
    int i;

    CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
    CAST_OBJ_NOTNULL(vef, priv, VEF_MAGIC);
    assert(l >= 0);

    if (vef->error) {
        vef->tot += l;
        return (vef->tot);
    }

    /*
     * l == 0 is valid when 'flg' calls for action, but in the
     * normal case we can just ignore a l==0 request.
     * (It would cause Z_BUF_ERROR anyway)
     */
    if (l == 0 && flg == VGZ_NORMAL)
        return (vef->tot);

    VGZ_Ibuf(vef->vgz, vef->ibuf_o, l);
    do {
        st = VFP_GetStorage(bo, 0);
        if (st == NULL) {
            vef->error = ENOMEM;
            vef->tot += l;
            return (vef->tot);
        }
        VGZ_Obuf(vef->vgz, st->ptr + st->len, st->space - st->len);
        i = VGZ_Gzip(vef->vgz, &dp, &dl, flg);
        vef->tot += dl;
        VBO_extend(bo, dl);
    } while (i != VGZ_ERROR &&
             (!VGZ_IbufEmpty(vef->vgz) || VGZ_ObufFull(vef->vgz)));
    assert(i == VGZ_ERROR || VGZ_IbufEmpty(vef->vgz));
    vef->ibuf_o += l;
    return (vef->tot);
}
Example #12
0
vfp_testgzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes)
{
	struct vgz *vg;
	ssize_t l, wl;
	int i = -100;
	size_t dl;
	const void *dp;
	struct storage *st;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	vg = bo->vgz_rx;
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	AZ(vg->vz.avail_in);
	while (bytes > 0) {
		st = FetchStorage(bo, 0);
		if (st == NULL)
			return(-1);
		l = st->space - st->len;
		if (l > bytes)
			l = bytes;
		wl = HTC_Read(htc, st->ptr + st->len, l);
		if (wl <= 0)
			return (wl);
		bytes -= wl;
		VGZ_Ibuf(vg, st->ptr + st->len, wl);
		st->len += wl;
		bo->fetch_obj->len += wl;

		while (!VGZ_IbufEmpty(vg)) {
			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
			i = VGZ_Gunzip(vg, &dp, &dl);
			if (i == VGZ_END && !VGZ_IbufEmpty(vg))
				return(FetchError(bo, "Junk after gzip data"));
			if (i != VGZ_OK && i != VGZ_END)
				return(FetchError2(bo,
				    "Invalid Gzip data", vg->vz.msg));
		}
	}
	assert(i == VGZ_OK || i == VGZ_END);
	return (1);
}
Example #13
0
VDP_gunzip(struct req *req, enum vdp_action act, const void *ptr, ssize_t len)
{
	enum vgzret_e vr;
	size_t dl;
	const void *dp;
	struct worker *wrk;
	struct vgz *vg;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	wrk = req->wrk;
	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	vg = req->vgz;
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	AN(vg->m_buf);

	if (len == 0) {
		AN(act > VDP_NULL);
		return (VDP_bytes(req, act, vg->m_buf, vg->m_len));
	}

	VGZ_Ibuf(vg, ptr, len);
	do {
		if (vg->m_len == vg->m_sz)
			vr = VGZ_STUCK;
		else {
			vr = VGZ_Gunzip(vg, &dp, &dl);
			vg->m_len += dl;
		}
		if (vr < VGZ_OK)
			return (-1);
		if (vg->m_len == vg->m_sz || vr == VGZ_STUCK) {
			if (VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len))
				return (-1);
			vg->m_len = 0;
			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
		}
	} while (!VGZ_IbufEmpty(vg));
	assert(vr == VGZ_STUCK || vr == VGZ_OK || vr == VGZ_END);
	return (0);
}
Example #14
0
vfp_testgunzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
    ssize_t *lp)
{
	struct vgz *vg;
	enum vgzret_e vr = VGZ_ERROR;
	const void *dp;
	ssize_t dl;
	enum vfp_status vp;

	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
	AN(p);
	AN(lp);
	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
	vp = VFP_Suck(vc, p, lp);
	if (vp == VFP_ERROR)
		return (vp);
	if (*lp > 0 || vp == VFP_END) {
		VGZ_Ibuf(vg, p, *lp);
		do {
			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
			vr = VGZ_Gunzip(vg, &dp, &dl);
			if (vr == VGZ_END && !VGZ_IbufEmpty(vg))
				return(VFP_Error(vc, "Junk after gzip data"));
			if (vr < VGZ_OK)
				return (VFP_Error(vc,
				    "Invalid Gzip data: %s", vgz_msg(vg)));
		} while (!VGZ_IbufEmpty(vg));
	}
	VGZ_UpdateObj(vc, vg, VUA_UPDATE);
	if (vp == VFP_END) {
		if (vr != VGZ_END)
			return (VFP_Error(vc, "tGunzip failed"));
		VGZ_UpdateObj(vc, vg, VUA_END_GUNZIP);
	}
	return (vp);
}
Example #15
0
vfp_testgunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
    ssize_t *lp)
{
	struct vgz *vg;
	enum vgzret_e vr = VGZ_ERROR;
	const void *dp;
	size_t dl;
	enum vfp_status vp;

        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
        AN(p);
        AN(lp);
	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
	vp = VFP_Suck(bo, p, lp);
	if (vp == VFP_ERROR)
		return (vp);
	if (*lp > 0 || vp == VFP_END) {
		VGZ_Ibuf(vg, p, *lp);
		do {
			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
			vr = VGZ_Gunzip(vg, &dp, &dl);
			if (vr == VGZ_END && !VGZ_IbufEmpty(vg))
				return(VFP_Error(bo, "Junk after gzip data"));
			if (vr < VGZ_OK)
				return (VFP_Error(bo,
				    "Invalid Gzip data: %s", vg->vz.msg));
		} while (!VGZ_IbufEmpty(vg));
	}
	if (vp == VFP_END) {
		if (vr != VGZ_END)
			return (VFP_Error(bo, "tGunzip failed"));
		VGZ_UpdateObj(vg, bo->fetch_obj);
	}
	return (vp);
}
Example #16
0
int
VGZ_WrwGunzip(struct worker *wrk, struct vgz *vg, const void *ibuf,
    ssize_t ibufl)
{
	int i;
	size_t dl;
	const void *dp;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	AN(vg->m_buf);
	VGZ_Ibuf(vg, ibuf, ibufl);
	if (ibufl == 0)
		return (VGZ_OK);
	do {
		if (vg->m_len == vg->m_sz)
			i = VGZ_STUCK;
		else {
			i = VGZ_Gunzip(vg, &dp, &dl);
			vg->m_len += dl;
		}
		if (i < VGZ_OK) {
			/* XXX: VSL ? */
			return (-1);
		}
		if (vg->m_len == vg->m_sz || i == VGZ_STUCK) {
			wrk->acct_tmp.bodybytes += vg->m_len;
			(void)WRW_Write(wrk, vg->m_buf, vg->m_len);
			(void)WRW_Flush(wrk);
			vg->m_len = 0;
			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
		}
	} while (!VGZ_IbufEmpty(vg));
	if (i == VGZ_STUCK)
		i = VGZ_OK;
	return (i);
}
Example #17
0
enum vgzret_e
VGZ_WrwGunzip(struct req *req, struct vgz *vg, const void *ibuf,
    ssize_t ibufl)
{
	enum vgzret_e vr;
	size_t dl;
	const void *dp;
	struct worker *wrk;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	wrk = req->wrk;
	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	AN(vg->m_buf);
	VGZ_Ibuf(vg, ibuf, ibufl);
	if (ibufl == 0)
		return (VGZ_OK);
	do {
		if (vg->m_len == vg->m_sz)
			vr = VGZ_STUCK;
		else {
			vr = VGZ_Gunzip(vg, &dp, &dl);
			vg->m_len += dl;
		}
		if (vr < VGZ_OK)
			return (vr);
		if (vg->m_len == vg->m_sz || vr == VGZ_STUCK) {
			(void)VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len);
			vg->m_len = 0;
			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
		}
	} while (!VGZ_IbufEmpty(vg));
	if (vr == VGZ_STUCK)
		vr = VGZ_OK;
	return (vr);
}
Example #18
0
VDP_gunzip(struct req *req, enum vdp_action act, void **priv,
    const void *ptr, ssize_t len)
{
	enum vgzret_e vr;
	ssize_t dl;
	const void *dp;
	struct worker *wrk;
	struct vgz *vg;
	const char *p;
	uint64_t u;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	wrk = req->wrk;
	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);

	if (act == VDP_INIT) {
		vg = VGZ_NewUngzip(req->vsl, "U D -");
		AN(vg);
		if (vgz_getmbuf(vg)) {
			(void)VGZ_Destroy(&vg);
			return (-1);
		}

		req->res_mode |= RES_GUNZIP;
		VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
		*priv = vg;

		http_Unset(req->resp, H_Content_Encoding);

		req->resp_len = -1;
		if (req->objcore->boc != NULL)
			return (0);	/* No idea about length (yet) */

		p = ObjGetAttr(req->wrk, req->objcore, OA_GZIPBITS, &dl);
		if (p == NULL || dl != 32)
			return (0); /* No OA_GZIPBITS yet */

		u = vbe64dec(p + 24);
		/*
		 * If the size is non-zero AND we are the top
		 * VDP (ie: no ESI), we know what size the output will be.
		 */
		if (u != 0 && VTAILQ_FIRST(&req->vdp)->func == VDP_gunzip)
			req->resp_len = u;

		return (0);
	}

	CAST_OBJ_NOTNULL(vg, *priv, VGZ_MAGIC);
	AN(vg->m_buf);

	if (act == VDP_FINI) {
		/* NB: Gunzip'ing may or may not have completed successfully. */
		AZ(len);
		(void)VGZ_Destroy(&vg);
		*priv = NULL;
		return (0);
	}

	if (len == 0)
		return (0);

	VGZ_Ibuf(vg, ptr, len);
	do {
		vr = VGZ_Gunzip(vg, &dp, &dl);
		vg->m_len += dl;
		if (vr < VGZ_OK)
			return (-1);
		if (vg->m_len == vg->m_sz || vr != VGZ_OK) {
			if (VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len))
				return (req->vdp_retval);
			vg->m_len = 0;
			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
		}
	} while (!VGZ_IbufEmpty(vg));
	assert(vr == VGZ_STUCK || vr == VGZ_OK || vr == VGZ_END);
	return (0);
}
Example #19
0
VDP_gunzip(struct req *req, enum vdp_action act, void **priv,
    const void *ptr, ssize_t len)
{
	enum vgzret_e vr;
	ssize_t dl;
	const void *dp;
	struct worker *wrk;
	struct vgz *vg;
	char *p;
	uint64_t u;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	wrk = req->wrk;
	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);

	if (act == VDP_INIT) {
		vg = VGZ_NewUngzip(req->vsl, "U D -");
		AN(vg);
		if (vgz_getmbuf(vg)) {
			(void)VGZ_Destroy(&vg);
			return (-1);
		}
		VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
		*priv = vg;

		http_Unset(req->resp, H_Content_Length);
		p = ObjGetattr(req->wrk, req->objcore, OA_GZIPBITS, &dl);
		if (p != NULL && dl == 32) {
			u = vbe64dec(p + 24);
			/* XXX: Zero is suspect: OA_GZIPBITS wasn't set */
			if (u != 0)
				http_PrintfHeader(req->resp,
				    "Content-Length: %ju", (uintmax_t)u);
		}
		http_Unset(req->resp, H_Content_Encoding);
		return (0);
	}

	CAST_OBJ_NOTNULL(vg, *priv, VGZ_MAGIC);
	AN(vg->m_buf);

	if (act == VDP_FINI) {
		/* NB: Gunzip'ing may or may not have completed successfully. */
		AZ(len);
		(void)VGZ_Destroy(&vg);
		*priv = NULL;
		return (0);
	}

	if (len == 0)
		return (0);

	VGZ_Ibuf(vg, ptr, len);
	do {
		vr = VGZ_Gunzip(vg, &dp, &dl);
		vg->m_len += dl;
		if (vr < VGZ_OK)
			return (-1);
		if (vg->m_len == vg->m_sz || vr != VGZ_OK) {
			if (VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len))
				return (-1);
			vg->m_len = 0;
			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
		}
	} while (!VGZ_IbufEmpty(vg));
	assert(vr == VGZ_STUCK || vr == VGZ_OK || vr == VGZ_END);
	return (0);
}