Author: rhuijben Date: Wed Nov 11 13:25:41 2015 New Revision: 1713837 URL: http://svn.apache.org/viewvc?rev=1713837&view=rev Log: Make the limit stream pass readline requests while still guarding the limit.
* buckets/limit_buckets.c (serf_limit_read): Simplify check a bit. (serf_limit_readline2, serf_limit_readline): New function. (serf_limit_read_iovec): Simplify check a bit. (serf_bucket_type_limit): Register new functions. Modified: serf/trunk/buckets/limit_buckets.c Modified: serf/trunk/buckets/limit_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/limit_buckets.c?rev=1713837&r1=1713836&r2=1713837&view=diff ============================================================================== --- serf/trunk/buckets/limit_buckets.c (original) +++ serf/trunk/buckets/limit_buckets.c Wed Nov 11 13:25:41 2015 @@ -54,12 +54,8 @@ static apr_status_t serf_limit_read(serf return APR_EOF; } - if (requested == SERF_READ_ALL_AVAIL || requested > ctx->remaining) { - if (ctx->remaining <= REQUESTED_MAX) { - requested = (apr_size_t) ctx->remaining; - } else { - requested = REQUESTED_MAX; - } + if (requested > ctx->remaining) { + requested = (apr_size_t) ctx->remaining; } status = serf_bucket_read(ctx->stream, requested, data, len); @@ -79,6 +75,53 @@ static apr_status_t serf_limit_read(serf return status; } +static apr_status_t serf_limit_readline2(serf_bucket_t *bucket, + int accepted, + apr_size_t requested, + int *found, + const char **data, + apr_size_t *len) +{ + limit_context_t *ctx = bucket->data; + apr_status_t status; + + if (!ctx->remaining) { + *len = 0; + return APR_EOF; + } + + if (requested > ctx->remaining) { + requested = (apr_size_t) ctx->remaining; + } + + status = serf_bucket_readline2(ctx->stream, accepted, + requested, found, data, len); + + if (!SERF_BUCKET_READ_ERROR(status)) { + ctx->remaining -= *len; + + /* If we have met our limit and don't have a status, return EOF. */ + if (!ctx->remaining && !status) { + status = APR_EOF; + } + else if (APR_STATUS_IS_EOF(status) && ctx->remaining) { + status = SERF_ERROR_TRUNCATED_HTTP_RESPONSE; + } + } + + return status; +} + +static apr_status_t serf_limit_readline(serf_bucket_t *bucket, + int accepted, + int *found, + const char **data, + apr_size_t *len) +{ + return serf_limit_readline2(bucket, accepted, SERF_READ_ALL_AVAIL, + found, data, len); +} + static apr_status_t serf_limit_read_iovec(serf_bucket_t *bucket, apr_size_t requested, int vecs_size, @@ -93,12 +136,8 @@ static apr_status_t serf_limit_read_iove return APR_EOF; } - if (requested == SERF_READ_ALL_AVAIL || requested > ctx->remaining) { - if (ctx->remaining <= REQUESTED_MAX) { - requested = (apr_size_t) ctx->remaining; - } else { - requested = REQUESTED_MAX; - } + if (requested > ctx->remaining) { + requested = (apr_size_t) ctx->remaining; } status = serf_bucket_read_iovec(ctx->stream, requested, @@ -169,14 +208,14 @@ static apr_status_t serf_limit_set_confi const serf_bucket_type_t serf_bucket_type_limit = { "LIMIT", serf_limit_read, - serf_default_readline, + serf_limit_readline, serf_limit_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, serf_limit_peek, serf_limit_destroy, serf_default_read_bucket, - serf_default_readline2, + serf_limit_readline2, serf_limit_get_remaining, serf_limit_set_config, };