static int
fetch_chunked(struct worker *wrk, struct http_conn *htc)
{
	int i;
	char buf[20];		/* XXX: 20 is arbitrary */
	unsigned u;
	ssize_t cl;

	assert(wrk->busyobj->body_status == BS_CHUNKED);
	do {
		/* Skip leading whitespace */
		do {
			if (HTC_Read(wrk, htc, buf, 1) <= 0)
				return (-1);
		} while (vct_islws(buf[0]));

		if (!vct_ishex(buf[0]))
			return (FetchError(wrk,"chunked header non-hex"));

		/* Collect hex digits, skipping leading zeros */
		for (u = 1; u < sizeof buf; u++) {
			do {
				if (HTC_Read(wrk, htc, buf + u, 1) <= 0)
					return (-1);
			} while (u == 1 && buf[0] == '0' && buf[u] == '0');
			if (!vct_ishex(buf[u]))
				break;
		}

		if (u >= sizeof buf)
			return (FetchError(wrk,"chunked header too long"));

		/* Skip trailing white space */
		while(vct_islws(buf[u]) && buf[u] != '\n')
			if (HTC_Read(wrk, htc, buf + u, 1) <= 0)
				return (-1);

		if (buf[u] != '\n')
			return (FetchError(wrk,"chunked header no NL"));

		buf[u] = '\0';
		cl = fetch_number(buf, 16);
		if (cl < 0)
			return (FetchError(wrk,"chunked header number syntax"));

		if (cl > 0 && wrk->busyobj->vfp->bytes(wrk, htc, cl) <= 0)
			return (-1);

		i = HTC_Read(wrk, htc, buf, 1);
		if (i <= 0)
			return (-1);
		if (buf[0] == '\r' && HTC_Read(wrk, htc, buf, 1) <= 0)
			return (-1);
		if (buf[0] != '\n')
			return (FetchError(wrk,"chunked tail no NL"));
	} while (cl > 0);
	return (0);
}
Beispiel #2
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);
}
Beispiel #3
0
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);
		bo->fetch_obj->len += dl;
	} while (i != Z_STREAM_END);
	VGZ_UpdateObj(vg, bo->fetch_obj);
	if (VGZ_Destroy(&vg) != VGZ_END)
		return(FetchError(bo, "Gzip error at the very end"));
	return (0);
}
Beispiel #4
0
vfp_gunzip_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;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	vg = bo->vgz_rx;
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	AZ(vg->vz.avail_in);
	while (bytes > 0 || vg->vz.avail_in > 0) {
		if (vg->vz.avail_in == 0 && bytes > 0) {
			l = vg->m_sz;
			if (l > bytes)
				l = bytes;
			wl = HTC_Read(htc, vg->m_buf, l);
			if (wl <= 0)
				return (wl);
			VGZ_Ibuf(vg, vg->m_buf, wl);
			bytes -= wl;
		}

		if (VGZ_ObufStorage(bo, vg))
			return(-1);
		i = VGZ_Gunzip(vg, &dp, &dl);
		if (i != VGZ_OK && i != VGZ_END)
			return(FetchError(bo, "Gunzip data error"));
		bo->fetch_obj->len += dl;
	}
	assert(i == Z_OK || i == Z_STREAM_END);
	return (1);
}
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);
}
static int
fetch_straight(struct worker *wrk, struct http_conn *htc, ssize_t cl)
{
	int i;

	assert(wrk->busyobj->body_status == BS_LENGTH);

	if (cl < 0) {
		return (FetchError(wrk, "straight length field bogus"));
	} else if (cl == 0)
		return (0);

	i = wrk->busyobj->vfp->bytes(wrk, htc, cl);
	if (i <= 0)
		return (FetchError(wrk, "straight insufficient bytes"));
	return (0);
}
Beispiel #7
0
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(FetchError(bo, "Gunzip error at the very end"));
	return (0);
}
Beispiel #8
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);
}
Beispiel #9
0
const nglChar* nglKernel::OnError (uint& rError) const
{
  return FetchError(gpKernelErrorTable, NULL, rError);
}
const nglChar* nglContext::OnError (uint& rError) const
{
  return FetchError(gpContextErrorTable, NULL, rError);
}