Esempio n. 1
0
static int chunked_trailer(ACL_ASTREAM *astream, HTTP_CHAT_CTX *ctx)
{
	HTTP_BODY_NOTIFY notify = ctx->notify.body_notify;
	void *arg = ctx->arg;
	ACL_VSTRING *sbuf;
	char *data;
	int   dlen;

	sbuf = acl_aio_gets_peek(astream);
	if (sbuf == NULL)
		return (0);

	data = acl_vstring_str(sbuf);
	dlen = (int) ACL_VSTRING_LEN(sbuf);
	ACL_VSTRING_RESET(sbuf);

	ctx->body_len += dlen;

	if (strcmp(data, "\r\n") == 0 || strcmp(data, "\n") == 0) {
		DISABLE_READ(astream);
		if ((dlen = notify(HTTP_CHAT_OK, data, dlen, arg)) < 0)
			return (-1);
		return (1);
	}
	if (notify(HTTP_CHAT_CHUNK_TRAILER, data, dlen, arg) < 0)
		return (-1);
	return (0);
}
Esempio n. 2
0
static int hdr_can_read(ACL_ASTREAM *astream, void *context)
{
	HTTP_CHAT_CTX *ctx = (HTTP_CHAT_CTX *) context;
	HTTP_HDR *hdr = ctx->hdr;
	HTTP_HDR_NOTIFY notify = ctx->notify.hdr_notify;
	void *arg = ctx->arg;
	ACL_VSTRING *sbuf;
	char *data;
	int   dlen;
	int   ret;

	while (1) {
		if ((ret = acl_aio_can_read(astream)) == ACL_VSTREAM_EOF) {
			notify(HTTP_CHAT_ERR_IO, arg);
			return (-1);
		} else if (ret == 0) {
			break;
		}
		sbuf = acl_aio_gets_nonl_peek(astream);
		if (sbuf == NULL) {
			break;
		}
		data = acl_vstring_str(sbuf);
		dlen = (int) ACL_VSTRING_LEN(sbuf);
		ACL_VSTRING_RESET(sbuf);

		ret = hdr_ready(hdr, data, dlen);
		switch (ret) {
		case HTTP_CHAT_CONTINUE:
			break;
		case HTTP_CHAT_OK:
			DISABLE_READ(astream);
			if (notify(ret, arg) < 0) {
				return (0);
			}
			return (0);
		default:
			DISABLE_READ(astream);
			(void) notify(ret, arg);
			return (0);
		}
	}

	acl_aio_enable_read(astream, hdr_can_read, ctx);
	return (0);
}
Esempio n. 3
0
static int chunked_data(ACL_ASTREAM *astream, HTTP_CHAT_CTX *ctx)
{
	HTTP_BODY_NOTIFY notify = ctx->notify.body_notify;
	void *arg = ctx->arg;
	ACL_VSTRING *sbuf;
	char *data;
	int   dlen, ret;

	if (ctx->chunked) {
		ret = (int) HTTP_LEN_ROUND(ctx);
		sbuf = acl_aio_readn_peek(astream, ret);
	} else if (ctx->hdr->content_length <= 0) {
		sbuf = acl_aio_read_peek(astream);
	} else {
		ret = (int) HTTP_LEN_ROUND(ctx);
		sbuf = acl_aio_readn_peek(astream, ret);
	}

	if (sbuf == NULL) {
		return (0);
	}

	data = acl_vstring_str(sbuf);
	dlen = (int) ACL_VSTRING_LEN(sbuf);
	ACL_VSTRING_RESET(sbuf);

	ctx->body_len += dlen;
	ctx->read_cnt += dlen;

	if (ctx->chunk_len > 0 && ctx->read_cnt >= ctx->chunk_len) {
		if (!ctx->chunked) {
			/* xxx: 禁止连续读 */
			DISABLE_READ(astream);
			if (notify(HTTP_CHAT_OK, data, dlen, arg) < 0)
				return (-1);
			return (1);
		}

		if (notify(HTTP_CHAT_DATA, data, dlen, arg) < 0)
			return (-1);

		/* 设置标志位开始读取块数据体的分隔行数据 */
		ctx->status = CHAT_S_CHUNK_SEP;
		return (0);
	}

	if (notify(HTTP_CHAT_DATA, data, dlen, arg) < 0)
		return (-1);
	return (0);
}
Esempio n. 4
0
static int chunked_data(ACL_ASTREAM *astream, HTTP_CHAT_CTX *ctx)
{
	HTTP_BODY_NOTIFY notify = ctx->notify.body_notify;
	void *arg = ctx->arg;
	ACL_VSTRING *sbuf = NULL;
	char *data;
	int   dlen, ret;

	if (ctx->chunked) {
		ret = (int) HTTP_LEN_ROUND(ctx);
		sbuf = acl_aio_readn_peek(astream, ret);
	} else if (ctx->hdr->content_length <= 0)
		sbuf = acl_aio_read_peek(astream);
	else {
		ret = (int) HTTP_LEN_ROUND(ctx);
		if (ret <= 0) {
			/* 说明本次 HTTP 数据已经读完且遇到对方关闭
			 * 或对方发来了多余的数据,所以需要返回 -1
			 */
			DISABLE_READ(astream);
			if (notify(HTTP_CHAT_OK, NULL, 0, arg) < 0)
				return (-1);
			return (-1);
		} else
			sbuf = acl_aio_readn_peek(astream, ret);
	}

	if (sbuf == NULL)
		return (0);

	data = acl_vstring_str(sbuf);
	dlen = (int) ACL_VSTRING_LEN(sbuf);
	ACL_VSTRING_RESET(sbuf);

	ctx->body_len += dlen;
	ctx->read_cnt += dlen;

	if (ctx->chunk_len > 0 && ctx->read_cnt >= ctx->chunk_len) {
		if (!ctx->chunked) {
			/* 如果读到完了整块数据且非 CHUNK 传输,
			 * 则认为读完 HTTP 响应
			 */
			/* xxx: 禁止连续读 */
			DISABLE_READ(astream);
			if (notify(HTTP_CHAT_OK, data, dlen, arg) < 0)
				return (-1);
			return (1);
		}

		/* 对于 chunk 传输,读完本数据块 */
		if (notify(HTTP_CHAT_DATA, data, dlen, arg) < 0)
			return (-1);

		/* 设置标志位开始读取块数据体的分隔行数据 */
		ctx->status = CHAT_S_CHUNK_SEP;
		return (0);
	}

	if (notify(HTTP_CHAT_DATA, data, dlen, arg) < 0)
		return (-1);
	return (0);
}