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); }
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); }