コード例 #1
0
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);
}
コード例 #2
0
ファイル: cache_gzip.c プロジェクト: ambernetas/varnish-cache
vfp_gzip_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 || !VGZ_IbufEmpty(vg)) {
		if (VGZ_IbufEmpty(vg) && 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_Gzip(vg, &dp, &dl, VGZ_NORMAL);
		assert(i == Z_OK);
		bo->fetch_obj->len += dl;
	}
	return (1);
}
コード例 #3
0
ファイル: cache_gzip.c プロジェクト: ambernetas/varnish-cache
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);
}
コード例 #4
0
int
FetchReqBody(const struct sess *sp)
{
	unsigned long content_length;
	char buf[8192];
	char *ptr, *endp;
	int rdcnt;

	if (http_GetHdr(sp->req->http, H_Content_Length, &ptr)) {

		content_length = strtoul(ptr, &endp, 10);
		/* XXX should check result of conversion */
		while (content_length) {
			if (content_length > sizeof buf)
				rdcnt = sizeof buf;
			else
				rdcnt = content_length;
			rdcnt = HTC_Read(sp->wrk, sp->req->htc, buf, rdcnt);
			if (rdcnt <= 0)
				return (1);
			content_length -= rdcnt;
			if (!sp->req->sendbody)
				continue;
			(void)WRW_Write(sp->wrk, buf, rdcnt); /* XXX: stats ? */
			if (WRW_Flush(sp->wrk))
				return (2);
		}
	}
	if (http_GetHdr(sp->req->http, H_Transfer_Encoding, NULL)) {
		/* XXX: Handle chunked encoding. */
		WSP(sp, SLT_Debug, "Transfer-Encoding in request");
		return (1);
	}
	return (0);
}
コード例 #5
0
vfp_nop_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes)
{
	ssize_t l, w;
	struct storage *st;

	while (bytes > 0) {
		st = FetchStorage(sp, 0);
		if (st == NULL) {
			htc->error = "Could not get storage";
			return (-1);
		}
		l = st->space - st->len;
		if (l > bytes)
			l = bytes;
		w = HTC_Read(htc, st->ptr + st->len, l);
		if (w <= 0)
			return (w);
		st->len += w;
		sp->obj->len += w;
		bytes -= w;
		if (sp->wrk->do_stream)
			RES_StreamPoll(sp);
	}
	return (1);
}
コード例 #6
0
static ssize_t
vef_read(struct http_conn *htc, void *buf, ssize_t buflen, ssize_t bytes)
{
	ssize_t d;

	if (buflen < bytes)
		bytes = buflen;
	if (params->esi_syntax & 0x8) {
		d = (random() & 3) + 1;
		if (d < bytes)
			bytes = d;
	}
	return (HTC_Read(htc, buf, bytes));
}
コード例 #7
0
ファイル: cache_gzip.c プロジェクト: ambernetas/varnish-cache
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);
}
コード例 #8
0
vfp_nop_bytes(struct worker *wrk, struct http_conn *htc, ssize_t bytes)
{
	ssize_t l, wl;
	struct storage *st;

	AZ(wrk->busyobj->fetch_failed);
	while (bytes > 0) {
		st = FetchStorage(wrk, 0);
		if (st == NULL)
			return(-1);
		l = st->space - st->len;
		if (l > bytes)
			l = bytes;
		wl = HTC_Read(wrk, htc, st->ptr + st->len, l);
		if (wl <= 0)
			return (wl);
		st->len += wl;
		wrk->busyobj->fetch_obj->len += wl;
		bytes -= wl;
		if (wrk->busyobj->do_stream)
			RES_StreamPoll(wrk);
	}
	return (1);
}
コード例 #9
0
static int
fetch_chunked(struct sess *sp, struct http_conn *htc)
{
	int i;
	char buf[20];		/* XXX: 20 is arbitrary */
	unsigned u;
	ssize_t cl;

	sp->wrk->vfp->begin(sp, 0);
	assert(sp->wrk->body_status == BS_CHUNKED);
	do {
		/* Skip leading whitespace */
		do {
			i = HTC_Read(htc, buf, 1);
			CERR();
		} while (vct_islws(buf[0]));

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

		if (u >= sizeof buf) {
			WSP(sp, SLT_FetchError,	"chunked header too long");
			return (-1);
		}

		/* Skip trailing white space */
		while(vct_islws(buf[u]) && buf[u] != '\n') {
			i = HTC_Read(htc, buf + u, 1);
			CERR();
		}

		if (buf[u] != '\n') {
			WSP(sp, SLT_FetchError,	"chunked header char syntax");
			return (-1);
		}
		buf[u] = '\0';

		cl = fetch_number(buf, 16);
		if (cl < 0) {
			WSP(sp, SLT_FetchError,	"chunked header nbr syntax");
			return (-1);
		} else if (cl > 0) {
			i = sp->wrk->vfp->bytes(sp, htc, cl);
			CERR();
		}
		i = HTC_Read(htc, buf, 1);
		CERR();
		if (buf[0] == '\r') {
			i = HTC_Read(htc, buf, 1);
			CERR();
		}
		if (buf[0] != '\n') {
			WSP(sp, SLT_FetchError,	"chunked tail syntax");
			return (-1);
		}
	} while (cl > 0);
	return (0);
}