コード例 #1
0
ファイル: cache_gzip.c プロジェクト: Matt8109/Varnish-Cache
vfp_gzip_end(struct busyobj *bo)
{
	struct vgz *vg;
	size_t dl;
	const void *dp;
	int i;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	vg = bo->vgz_rx;
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	bo->vgz_rx = NULL;
	if (bo->state == BOS_FAILED) {
		(void)VGZ_Destroy(&vg);
		return(0);
	}
	do {
		VGZ_Ibuf(vg, "", 0);
		if (VGZ_ObufStorage(bo, vg))
			return(-1);
		i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH);
		VBO_extend(bo, dl);
	} while (i != Z_STREAM_END);
	VGZ_UpdateObj(vg, bo->fetch_obj);
	if (VGZ_Destroy(&vg) != VGZ_END)
		return(VFP_Error(bo, "Gzip error at the very end"));
	return (0);
}
コード例 #2
0
vfp_esi_end(struct sess *sp)
{
	struct vsb *vsb;
	struct vef_priv *vef;
	ssize_t l;

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	AN(sp->wrk->vep);

	vsb = VEP_Finish(sp);

	if (vsb != NULL) {
		l = VSB_len(vsb);
		assert(l > 0);
		/* XXX: This is a huge waste of storage... */
		sp->obj->esidata = STV_alloc(sp, l);
		XXXAN(sp->obj->esidata);
		memcpy(sp->obj->esidata->ptr, VSB_data(vsb), l);
		sp->obj->esidata->len = l;
		VSB_delete(vsb);
	}
	if (sp->wrk->vgz_rx != NULL)
		VGZ_Destroy(&sp->wrk->vgz_rx);

	if (sp->wrk->vef_priv != NULL) {
		vef = sp->wrk->vef_priv;
		CHECK_OBJ_NOTNULL(vef, VEF_MAGIC);
		sp->wrk->vef_priv = NULL;
		VGZ_UpdateObj(vef->vgz, sp->obj);
		VGZ_Destroy(&vef->vgz);
		XXXAZ(vef->error);
		FREE_OBJ(vef);
	}
	return (0);
}
コード例 #3
0
vfp_esi_end(struct busyobj *bo)
{
	struct vsb *vsb;
	struct vef_priv *vef;
	ssize_t l;
	int retval = 0;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	AN(bo->vep);

	if (bo->state == BOS_FAILED)
		retval = -1;

	if (bo->vgz_rx != NULL && VGZ_Destroy(&bo->vgz_rx) != VGZ_END)
		retval = VFP_Error(bo, "Gunzip+ESI Failed at the very end");

	vsb = VEP_Finish(bo);

	if (vsb != NULL) {
		if (!retval) {
			l = VSB_len(vsb);
			assert(l > 0);
			/* XXX: This is a huge waste of storage... */
			bo->fetch_obj->esidata = STV_alloc(bo, l);
			if (bo->fetch_obj->esidata != NULL) {
				memcpy(bo->fetch_obj->esidata->ptr,
				    VSB_data(vsb), l);
				bo->fetch_obj->esidata->len = l;
			} else {
				retval = VFP_Error(bo,
				    "Could not allocate storage for esidata");
			}
		}
		VSB_delete(vsb);
	}

	vef = bo->vef_priv;
	bo->vef_priv = NULL;
	CHECK_OBJ_NOTNULL(vef, VEF_MAGIC);
	if (vef->vgz != NULL) {
		VGZ_UpdateObj(vef->vgz, bo->fetch_obj);
		if (VGZ_Destroy(&vef->vgz) != VGZ_END)
			retval = VFP_Error(bo,
			    "ESI+Gzip Failed at the very end");
	}
	if (vef->ibuf != NULL)
		free(vef->ibuf);
	if (vef->ibuf2 != NULL)
		free(vef->ibuf2);
	FREE_OBJ(vef);
	return (retval);
}
コード例 #4
0
ファイル: cache_esi_fetch.c プロジェクト: acdha/Varnish-Cache
vfp_esi_end(struct worker *wrk)
{
	struct vsb *vsb;
	struct vef_priv *vef;
	struct busyobj *bo;
	ssize_t l;
	int retval;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	bo = wrk->busyobj;
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	AN(bo->vep);

	retval = bo->fetch_failed;

	if (bo->vgz_rx != NULL && VGZ_Destroy(&bo->vgz_rx, -1) != VGZ_END)
		retval = FetchError(wrk, "Gunzip+ESI Failed at the very end");

	vsb = VEP_Finish(wrk);

	if (vsb != NULL) {
		if (!retval) {
			l = VSB_len(vsb);
			assert(l > 0);
			/* XXX: This is a huge waste of storage... */
			bo->fetch_obj->esidata = STV_alloc(wrk, l);
			if (bo->fetch_obj->esidata != NULL) {
				memcpy(bo->fetch_obj->esidata->ptr,
				    VSB_data(vsb), l);
				bo->fetch_obj->esidata->len = l;
			} else {
				retval = FetchError(wrk,
				    "Could not allocate storage for esidata");
			}
		}
		VSB_delete(vsb);
	}

	vef = bo->vef_priv;
	if (vef != NULL) {
		CHECK_OBJ_NOTNULL(vef, VEF_MAGIC);
		bo->vef_priv = NULL;
		VGZ_UpdateObj(vef->vgz, bo->fetch_obj);
		if (VGZ_Destroy(&vef->vgz,  -1) != VGZ_END)
			retval = FetchError(wrk,
			    "ESI+Gzip Failed at the very end");
		FREE_OBJ(vef);
	}
	return (retval);
}
コード例 #5
0
ファイル: cache_gzip.c プロジェクト: Matt8109/Varnish-Cache
vfp_gunzip_end(struct busyobj *bo)
{
	struct vgz *vg;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	vg = bo->vgz_rx;
	bo->vgz_rx = NULL;
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	if (bo->state == BOS_FAILED) {
		(void)VGZ_Destroy(&vg);
		return(0);
	}
	if (VGZ_Destroy(&vg) != VGZ_END)
		return(VFP_Error(bo, "Gunzip error at the very end"));
	return (0);
}
コード例 #6
0
ファイル: cache_gzip.c プロジェクト: ambernetas/varnish-cache
vfp_testgzip_end(struct busyobj *bo)
{
	struct vgz *vg;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	vg = bo->vgz_rx;
	bo->vgz_rx = NULL;
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	if (bo->state == BOS_FAILED) {
		(void)VGZ_Destroy(&vg);
		return(0);
	}
	VGZ_UpdateObj(vg, bo->fetch_obj);
	if (VGZ_Destroy(&vg) != VGZ_END)
		return(FetchError(bo, "TestGunzip error at the very end"));
	return (0);
}
コード例 #7
0
vfp_gzip_fini(struct vfp_ctx *vc, struct vfp_entry *vfe)
{
	struct vgz *vg;

	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);

	if (vfe->priv1 != NULL) {
		CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
		vfe->priv1 = NULL;
		(void)VGZ_Destroy(&vg);
	}
}
コード例 #8
0
ファイル: cache_gzip.c プロジェクト: nublaii/Varnish-Cache
vfp_gzip_fini(struct busyobj *bo, struct vfp_entry *vfe)
{
	struct vgz *vg;

        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);

	if (vfe->priv1 != NULL) {
		CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
		vfe->priv1 = NULL;
		(void)VGZ_Destroy(&vg);
	}
}
コード例 #9
0
static enum vfp_status
vfp_esi_end(struct busyobj *bo, struct vef_priv *vef, enum vfp_status retval)
{
    struct vsb *vsb;
    ssize_t l;

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

    vsb = VEP_Finish(vef->vep, bo);

    if (vsb != NULL) {
        if (retval == VFP_END) {
            l = VSB_len(vsb);
            assert(l > 0);
            /* XXX: This is a huge waste of storage... */
            bo->fetch_obj->esidata = STV_alloc(bo, l);
            if (bo->fetch_obj->esidata != NULL) {
                memcpy(bo->fetch_obj->esidata->ptr,
                VSB_data(vsb), l);
                bo->fetch_obj->esidata->len = l;
            } else {
                retval = VFP_Error(bo,
                                   "Could not allocate storage for esidata");
            }
        }
        VSB_delete(vsb);
    }

    if (vef->vgz != NULL) {
        VGZ_UpdateObj(vef->vgz, bo->fetch_obj);
        if (VGZ_Destroy(&vef->vgz) != VGZ_END)
            retval = VFP_Error(bo,
                               "ESI+Gzip Failed at the very end");
    }
    if (vef->ibuf != NULL)
        free(vef->ibuf);
    FREE_OBJ(vef);
    return (retval);
}
コード例 #10
0
ファイル: cache_esi_fetch.c プロジェクト: feld/Varnish-Cache
static enum vfp_status
vfp_esi_end(struct vfp_ctx *vc, struct vef_priv *vef,
    enum vfp_status retval)
{
	struct vsb *vsb;
	ssize_t l;
	void *p;

	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vef, VEF_MAGIC);

	vsb = VEP_Finish(vef->vep);

	if (vsb != NULL) {
		if (retval == VFP_END) {
			l = VSB_len(vsb);
			assert(l > 0);
			p = ObjSetattr(vc->wrk, vc->oc,
			    OA_ESIDATA, l, VSB_data(vsb));
			if (p == NULL) {
				retval = VFP_Error(vc,
				    "Could not allocate storage for esidata");
			}
		}
		VSB_delete(vsb);
	}

	if (vef->vgz != NULL) {
		VGZ_UpdateObj(vc, vef->vgz, VUA_END_GZIP);
		if (VGZ_Destroy(&vef->vgz) != VGZ_END)
			retval = VFP_Error(vc,
			    "ESI+Gzip Failed at the very end");
	}
	if (vef->ibuf != NULL)
		free(vef->ibuf);
	FREE_OBJ(vef);
	return (retval);
}
コード例 #11
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);
}
コード例 #12
0
ファイル: cache_gzip.c プロジェクト: biddyweb/Varnish-Cache
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);
}
コード例 #13
0
void
V1D_Deliver(struct req *req)
{
	char *r;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
	CHECK_OBJ_NOTNULL(req->obj->objcore, OBJCORE_MAGIC);

	req->res_mode = 0;

	if (!req->disable_esi && req->obj->esidata != NULL) {
		/* In ESI mode, we can't know the aggregate length */
		req->res_mode &= ~RES_LEN;
		req->res_mode |= RES_ESI;
	} else if (req->resp->status == 304) {
		req->res_mode &= ~RES_LEN;
		http_Unset(req->resp, H_Content_Length);
		req->wantbody = 0;
	} else if (req->obj->objcore->busyobj == NULL) {
		/* XXX: Not happy with this convoluted test */
		req->res_mode |= RES_LEN;
		if (!(req->obj->objcore->flags & OC_F_PASS) ||
		    req->obj->len != 0) {
			http_Unset(req->resp, H_Content_Length);
			http_PrintfHeader(req->resp,
			    "Content-Length: %zd", req->obj->len);
		}
	}

	if (req->esi_level > 0) {
		/* Included ESI object, always CHUNKED or EOF */
		req->res_mode &= ~RES_LEN;
		req->res_mode |= RES_ESI_CHILD;
	}

	if (cache_param->http_gzip_support && req->obj->gziped &&
	    !RFC2616_Req_Gzip(req->http)) {
		/*
		 * We don't know what it uncompresses to
		 * XXX: we could cache that, but would still deliver
		 * XXX: with multiple writes because of the gunzip buffer
		 */
		req->res_mode &= ~RES_LEN;
		req->res_mode |= RES_GUNZIP;
	}

	if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) {
		/* We havn't chosen yet, do so */
		if (!req->wantbody) {
			/* Nothing */
		} else if (req->http->protover >= 11) {
			req->res_mode |= RES_CHUNKED;
		} else {
			req->res_mode |= RES_EOF;
			req->doclose = SC_TX_EOF;
		}
	}
	VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode);

	if (!(req->res_mode & RES_LEN))
		http_Unset(req->resp, H_Content_Length);

	if (req->res_mode & RES_GUNZIP)
		http_Unset(req->resp, H_Content_Encoding);

	if (req->res_mode & RES_CHUNKED)
		http_SetHeader(req->resp, "Transfer-Encoding: chunked");

	http_SetHeader(req->resp,
	    req->doclose ? "Connection: close" : "Connection: keep-alive");

	req->vdps[0] = v1d_bytes;
	req->vdp_nxt = 0;

	if (
	    req->wantbody &&
	    !(req->res_mode & (RES_ESI|RES_ESI_CHILD)) &&
	    cache_param->http_range_support &&
	    req->obj->response == 200) {
		http_SetHeader(req->resp, "Accept-Ranges: bytes");
		if (http_GetHdr(req->http, H_Range, &r))
			v1d_dorange(req, r);
	}

	if (req->res_mode & RES_ESI)
		RFC2616_Weaken_Etag(req->resp);

	WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_resp);

	/*
	 * Send HTTP protocol header, unless interior ESI object
	 */
	if (!(req->res_mode & RES_ESI_CHILD))
		req->acct_req.hdrbytes += HTTP1_Write(req->wrk, req->resp, 1);

	if (req->res_mode & RES_CHUNKED)
		WRW_Chunked(req->wrk);

	if (!req->wantbody) {
		/* This was a HEAD or conditional request */
	} else if (req->res_mode & RES_ESI) {
		AZ(req->obj->objcore->busyobj);
		ESI_Deliver(req);
	} else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) {
		while (req->obj->objcore->busyobj)
			(void)usleep(10000);
		ESI_DeliverChild(req);
	} else if (req->res_mode & RES_GUNZIP ||
	    (req->res_mode & RES_ESI_CHILD &&
	    !req->gzip_resp && req->obj->gziped)) {
		VDP_push(req, VDP_gunzip);
		req->vgz = VGZ_NewUngzip(req->vsl, "U D -");
		AZ(VGZ_WrwInit(req->vgz));
		v1d_WriteDirObj(req);
		(void)VGZ_Destroy(&req->vgz);
		VDP_pop(req, VDP_gunzip);
	} else {
		v1d_WriteDirObj(req);
	}

	if (req->res_mode & RES_CHUNKED && !(req->res_mode & RES_ESI_CHILD))
		WRW_EndChunk(req->wrk);

	if (WRW_FlushRelease(req->wrk) && req->sp->fd >= 0)
		SES_Close(req->sp, SC_REM_CLOSE);
}
コード例 #14
0
static int
cnt_streambody(struct sess *sp)
{
    int i;
    struct stream_ctx sctx;
    uint8_t obuf[sp->wrk->res_mode & RES_GUNZIP ?
                 cache_param->gzip_stack_buffer : 1];
    struct worker *wrk;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    wrk = sp->wrk;
    CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);

    CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC);
    memset(&sctx, 0, sizeof sctx);
    sctx.magic = STREAM_CTX_MAGIC;
    AZ(wrk->sctx);
    wrk->sctx = &sctx;

    if (wrk->res_mode & RES_GUNZIP) {
        sctx.vgz = VGZ_NewUngzip(wrk, "U S -");
        sctx.obuf = obuf;
        sctx.obuf_len = sizeof (obuf);
    }

    RES_StreamStart(sp);

    AssertObjCorePassOrBusy(wrk->obj->objcore);

    i = FetchBody(wrk, wrk->obj);

    http_Setup(wrk->busyobj->bereq, NULL);
    http_Setup(wrk->busyobj->beresp, NULL);
    wrk->busyobj->vfp = NULL;
    AZ(wrk->busyobj->vbc);
    AN(sp->director);

    if (!i && wrk->obj->objcore != NULL) {
        EXP_Insert(wrk->obj);
        AN(wrk->obj->objcore);
        AN(wrk->obj->objcore->ban);
        HSH_Unbusy(wrk);
    } else {
        sp->doclose = "Stream error";
    }
    wrk->acct_tmp.fetch++;
    sp->director = NULL;
    sp->restarts = 0;

    RES_StreamEnd(sp);
    if (wrk->res_mode & RES_GUNZIP)
        (void)VGZ_Destroy(&sctx.vgz, sp->vsl_id);

    wrk->sctx = NULL;
    assert(WRW_IsReleased(wrk));
    assert(wrk->wrw.ciov == wrk->wrw.siov);
    (void)HSH_Deref(wrk, NULL, &wrk->obj);
    VBO_DerefBusyObj(wrk, &wrk->busyobj);
    http_Setup(wrk->resp, NULL);
    sp->step = STP_DONE;
    return (0);
}