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);
}
示例#2
0
struct storage *
VFP_GetStorage(struct busyobj *bo, ssize_t sz)
{
	ssize_t l;
	struct storage *st;
	struct object *obj;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	obj = bo->fetch_obj;
	CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
	st = VTAILQ_LAST(&obj->store, storagehead);
	if (st != NULL && st->len < st->space)
		return (st);

	AN(bo->stats);
	l = fetchfrag;
	if (l == 0)
		l = sz;
	if (l == 0)
		l = cache_param->fetch_chunksize;
	st = STV_alloc(bo, l);
	if (st == NULL) {
		(void)VFP_Error(bo, "Could not get storage");
	} else {
		AZ(st->len);
		Lck_Lock(&bo->mtx);
		VTAILQ_INSERT_TAIL(&obj->store, st, list);
		Lck_Unlock(&bo->mtx);
	}
	return (st);
}
struct storage *
FetchStorage(struct worker *wrk, ssize_t sz)
{
	ssize_t l;
	struct storage *st;
	struct object *obj;

	obj = wrk->busyobj->fetch_obj;
	CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
	st = VTAILQ_LAST(&obj->store, storagehead);
	if (st != NULL && st->len < st->space)
		return (st);

	l = fetchfrag;
	if (l == 0)
		l = sz;
	if (l == 0)
		l = cache_param->fetch_chunksize;
	st = STV_alloc(wrk, l);
	if (st == NULL) {
		(void)FetchError(wrk, "Could not get storage");
		return (NULL);
	}
	AZ(st->len);
	VTAILQ_INSERT_TAIL(&obj->store, st, list);
	return (st);
}
示例#4
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);
}
示例#5
0
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);
}
示例#6
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);
}
struct storage *
FetchStorage(const struct sess *sp, ssize_t sz)
{
	ssize_t l;
	struct storage *st;

	st = VTAILQ_LAST(&sp->obj->store, storagehead);
	if (st != NULL && st->len < st->space)
		return (st);

	l = fetchfrag;
	if (l == 0)
		l = sz;
	if (l == 0)
		l = params->fetch_chunksize * 1024LL;
	st = STV_alloc(sp, l);
	if (st == NULL) {
		errno = ENOMEM;
		return (NULL);
	}
	AZ(st->len);
	VTAILQ_INSERT_TAIL(&sp->obj->store, st, list);
	return (st);
}
示例#8
0
static enum fetch_step
vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
{
	struct object *obj;
	struct objiter *oi;
	void *sp;
	ssize_t sl, al, tl;
	struct storage *st;
	enum objiter_status ois;
	char *p;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);

	if (bo->ims_obj->changed_gzip) {
		/*
		 * If we modified the gzip status of the IMS object, that
		 * must control the C-E header, if any.
		 */
		http_Unset(bo->beresp, H_Content_Encoding);
		if (http_GetHdr(bo->ims_obj->http, H_Content_Encoding, &p))
			http_PrintfHeader(bo->beresp,
			    "Content-Encoding: %s", p);
	}

	AZ(vbf_beresp2obj(bo));
	obj = bo->fetch_obj;
	bo->vfc->body = obj->body;

	if (bo->ims_obj->esidata != NULL) {
		sl = bo->ims_obj->esidata->len;
		obj->esidata = STV_alloc(bo->vfc, sl);
		if (obj->esidata == NULL || obj->esidata->space < sl) {
			VSLb(bo->vsl, SLT_Error,
			    "No space for %zd bytes of ESI data", sl);
			return (F_STP_FAIL);
		}
		memcpy(obj->esidata->ptr, bo->ims_obj->esidata->ptr, sl);
		obj->esidata->len = sl;
	}

	obj->gziped = bo->ims_obj->gziped;
	obj->gzip_start = bo->ims_obj->gzip_start;
	obj->gzip_last = bo->ims_obj->gzip_last;
	obj->gzip_stop = bo->ims_obj->gzip_stop;

	AZ(WS_Overflowed(bo->ws_o));
	if (bo->do_stream) {
		HSH_Unbusy(&wrk->stats, obj->objcore);
		VBO_setstate(bo, BOS_STREAM);
	}

	st = NULL;
	al = 0;

	oi = ObjIterBegin(wrk, bo->ims_obj);
	do {
		ois = ObjIter(oi, &sp, &sl);
		while (sl > 0) {
			if (st == NULL)
				st = VFP_GetStorage(bo->vfc,
				    bo->ims_obj->len - al);
			if (st == NULL)
				break;
			tl = sl;
			if (tl > st->space - st->len)
				tl = st->space - st->len;
			memcpy(st->ptr + st->len, sp, tl);
			al += tl;
			sp = (char *)sp + tl;
			sl -= tl;
			VBO_extend(bo, tl);
			if (st->len == st->space)
				st = NULL;
		}
	} while (!bo->vfc->failed && (ois == OIS_DATA || ois == OIS_STREAM));
	ObjIterEnd(&oi);
	if (bo->vfc->failed)
		return (F_STP_FAIL);

	if (!bo->do_stream)
		HSH_Unbusy(&wrk->stats, obj->objcore);

	assert(al == bo->ims_obj->len);
	assert(obj->len == al);
	EXP_Rearm(bo->ims_obj->objcore,
	    bo->ims_obj->objcore->exp.t_origin, 0, 0, 0);

	/* Recycle the backend connection before setting BOS_FINISHED to
	   give predictable backend reuse behavior for varnishtest */
	if (bo->vbc != NULL && bo->doclose == SC_NULL) {
		VDI_RecycleFd(&bo->vbc, &bo->acct);
		AZ(bo->vbc);
	}

	VBO_setstate(bo, BOS_FINISHED);
	VSLb_ts_busyobj(bo, "BerespBody", W_TIM_real(wrk));
	return (F_STP_DONE);
}