in buckets/split_buckets.c [151:219]
static apr_status_t serf_split_read_iovec(serf_bucket_t *bucket,
apr_size_t requested,
int vecs_size,
struct iovec *vecs,
int *vecs_used)
{
split_stream_ctx_t *sctx = bucket->data;
split_context_t *ctx = sctx->ctx;
apr_status_t status;
if (! ctx || sctx->at_eof) {
split_detach_head(sctx);
*vecs_used = 0;
return APR_EOF;
}
else if (sctx->prev) {
/* Not the current head */
*vecs_used = 0;
if (sctx->prev->prev || !sctx->prev->at_eof)
return APR_EAGAIN; /* Not ready soon */
return APR_SUCCESS; /* Most likely ready at next read */
}
if (sctx->max_size != SERF_READ_ALL_AVAIL
&& requested > (sctx->max_size - sctx->read_size))
{
requested = (sctx->max_size - sctx->read_size);
}
status = serf_bucket_read_iovec(ctx->stream, requested, vecs_size,
vecs, vecs_used);
if (!SERF_BUCKET_READ_ERROR(status)) {
apr_size_t len = 0;
int i;
for (i = 0; i < *vecs_used; i++)
len += vecs[i].iov_len;
sctx->cant_read = (len != 0);
sctx->read_size += len;
if (sctx->min_size != SERF_READ_ALL_AVAIL
&& sctx->read_size >= sctx->min_size) {
/* We read enough. Fix the final length now */
sctx->at_eof = true;
sctx->fixed_size = sctx->max_size = sctx->read_size;
status = APR_EOF;
}
else if (APR_STATUS_IS_EOF(status)) {
sctx->at_eof = TRUE;
if (sctx->fixed_size && sctx->read_size != sctx->fixed_size) {
/* We promised more data via get_remaining() than we can
deliver. -> BAD get_remaining() */
status = SERF_ERROR_TRUNCATED_STREAM;
}
else {
/* Ok, then this is our size */
sctx->max_size = sctx->fixed_size = sctx->read_size;
}
}
}
else
sctx->cant_read = false;
return status;
}