Author: rhuijben Date: Wed Nov 25 10:35:59 2015 New Revision: 1716346 URL: http://svn.apache.org/viewvc?rev=1716346&view=rev Log: Don't retry reads of length 0 with success status until the end of time, while reading from another bucket. Just return a read of 0 itself.
* buckets/fcgi_buckets.c (serf__bucket_fcgi_unframe_read_info): Return special error here. (serf_fcgi_unframe_read, serf_fcgi_unframe_peek): And fold it into success here. * buckets/hpack_buckets.c (read_hpack_int): Return special error here... (hpack_read_bytes): ... and here. (serf_hpack_decode_read, serf_hpack_decode_peek): And fold it into success here. * buckets/http2_frame_buckets.c (serf__bucket_http2_unframe_read_info): Return special error here. (serf_http2_unframe_read, serf_http2_unframe_read_iovec, serf_http2_unframe_peek): And fold it into success here. * context.c (serf_error_string): Print new error. * serf.h (SERF_ERROR_EMPTY_READ): Declare new error. Modified: serf/trunk/buckets/fcgi_buckets.c serf/trunk/buckets/hpack_buckets.c serf/trunk/buckets/http2_frame_buckets.c serf/trunk/context.c serf/trunk/serf.h Modified: serf/trunk/buckets/fcgi_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/fcgi_buckets.c?rev=1716346&r1=1716345&r2=1716346&view=diff ============================================================================== --- serf/trunk/buckets/fcgi_buckets.c (original) +++ serf/trunk/buckets/fcgi_buckets.c Wed Nov 25 10:35:59 2015 @@ -96,6 +96,8 @@ apr_status_t serf__bucket_fcgi_unframe_r if (SERF_BUCKET_READ_ERROR(status)) return status; + else if (!len && !status) + return SERF_ERROR_EMPTY_READ; if (len < FCGI_RECORD_SIZE) { memcpy(ctx->buffer + FCGI_RECORD_SIZE - ctx->record_remaining, @@ -170,7 +172,7 @@ static apr_status_t serf_fcgi_unframe_re if (status) { *len = 0; - return status; + return (status == SERF_ERROR_EMPTY_READ) ? APR_SUCCESS : status; } if (requested > ctx->payload_remaining) @@ -219,7 +221,7 @@ static apr_status_t serf_fcgi_unframe_pe if (status) { *len = 0; - return status; + return (status == SERF_ERROR_EMPTY_READ) ? APR_SUCCESS : status; } status = serf_bucket_peek(ctx->stream, data, len); Modified: serf/trunk/buckets/hpack_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/hpack_buckets.c?rev=1716346&r1=1716345&r2=1716346&view=diff ============================================================================== --- serf/trunk/buckets/hpack_buckets.c (original) +++ serf/trunk/buckets/hpack_buckets.c Wed Nov 25 10:35:59 2015 @@ -1251,11 +1251,11 @@ read_hpack_int(apr_uint32_t *v, const char *data; apr_size_t len; - do { - status = serf_bucket_read(ctx->stream, 1, &data, &len); - } while ((status == APR_SUCCESS) && !len); + status = serf_bucket_read(ctx->stream, 1, &data, &len); - if (SERF_BUCKET_READ_ERROR(status) || len == 0) + if (!status && !len) + return SERF_ERROR_EMPTY_READ; + else if (SERF_BUCKET_READ_ERROR(status) || len == 0) return status; ctx->buffer[0] = *data; @@ -1291,11 +1291,10 @@ read_hpack_int(apr_uint32_t *v, if ((7 * (ctx->buffer_used - 1) + bits) >= 32) return SERF_ERROR_HTTP2_COMPRESSION_ERROR; - do { - status = serf_bucket_read(ctx->stream, 1, &data, &len); - } while ((status == APR_SUCCESS) && !len); - - if (SERF_BUCKET_READ_ERROR(status) || len == 0) + status = serf_bucket_read(ctx->stream, 1, &data, &len); + if (!status && !len) + return SERF_ERROR_EMPTY_READ; + else if (SERF_BUCKET_READ_ERROR(status) || len == 0) return status; ctx->buffer[ctx->buffer_used] = *data; @@ -1577,6 +1576,8 @@ static apr_status_t hpack_read_bytes(ser if (status) break; + else if (!status && !len) + return SERF_ERROR_EMPTY_READ; } if (ctx->buffer_used == required) @@ -1608,11 +1609,10 @@ hpack_process(serf_bucket_t *bucket) const char *data; apr_size_t len; - do { - status = serf_bucket_read(ctx->stream, 1, &data, &len); - } while (status == APR_SUCCESS && !len); - - if (SERF_BUCKET_READ_ERROR(status) || len == 0) + status = serf_bucket_read(ctx->stream, 1, &data, &len); + if (!status && !len) + return SERF_ERROR_EMPTY_READ; + else if (SERF_BUCKET_READ_ERROR(status) || len == 0) break; ctx->key_hm = ctx->val_hm = FALSE; @@ -1883,7 +1883,6 @@ hpack_process(serf_bucket_t *bucket) if (APR_STATUS_IS_EOF(status)) { - serf_bucket_t *b; if (ctx->state != HPACK_DECODE_STATE_INITIAL) return SERF_ERROR_HTTP2_COMPRESSION_ERROR; @@ -1911,10 +1910,10 @@ serf_hpack_decode_read(serf_bucket_t *bu apr_status_t status; status = hpack_process(bucket); - if (SERF_BUCKET_READ_ERROR(status) || !ctx->agg) + if (status || !ctx->agg) { *len = 0; - return status; + return (status == SERF_ERROR_EMPTY_READ) ? APR_SUCCESS : status; } return serf_bucket_read(ctx->agg, requested, data, len); @@ -1929,10 +1928,10 @@ serf_hpack_decode_peek(serf_bucket_t *bu apr_status_t status; status = hpack_process(bucket); - if (SERF_BUCKET_READ_ERROR(status) || !ctx->agg) + if (status || !ctx->agg) { *len = 0; - return status; + return (status == SERF_ERROR_EMPTY_READ) ? APR_SUCCESS : status; } return serf_bucket_peek(ctx->agg, data, len); Modified: serf/trunk/buckets/http2_frame_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/http2_frame_buckets.c?rev=1716346&r1=1716345&r2=1716346&view=diff ============================================================================== --- serf/trunk/buckets/http2_frame_buckets.c (original) +++ serf/trunk/buckets/http2_frame_buckets.c Wed Nov 25 10:35:59 2015 @@ -105,6 +105,8 @@ serf__bucket_http2_unframe_read_info(ser status = serf_bucket_read(ctx->stream, ctx->prefix_remaining, &data, &len); if (SERF_BUCKET_READ_ERROR(status)) return status; + else if (!status && !len) + return SERF_ERROR_EMPTY_READ; if (len < FRAME_PREFIX_SIZE) { memcpy(ctx->buffer + FRAME_PREFIX_SIZE - ctx->prefix_remaining, @@ -208,7 +210,7 @@ serf_http2_unframe_read(serf_bucket_t *b if (status) { *len = 0; - return status; + return (status == SERF_ERROR_EMPTY_READ) ? APR_SUCCESS : status; } if (ctx->payload_remaining == 0) { @@ -242,8 +244,8 @@ static apr_status_t serf_http2_unframe_read_iovec(serf_bucket_t *bucket, apr_size_t requested, int vecs_size, -struct iovec *vecs, - int *vecs_used) + struct iovec *vecs, + int *vecs_used) { http2_unframe_context_t *ctx = bucket->data; apr_status_t status; @@ -252,7 +254,7 @@ struct iovec *vecs, if (status) { *vecs_used = 0; - return status; + return (status == SERF_ERROR_EMPTY_READ) ? APR_SUCCESS : status; } if (ctx->payload_remaining == 0) { @@ -301,7 +303,7 @@ serf_http2_unframe_peek(serf_bucket_t *b if (status) { *len = 0; - return status; + return (status == SERF_ERROR_EMPTY_READ) ? APR_SUCCESS : status; } status = serf_bucket_peek(ctx->stream, data, len); Modified: serf/trunk/context.c URL: http://svn.apache.org/viewvc/serf/trunk/context.c?rev=1716346&r1=1716345&r2=1716346&view=diff ============================================================================== --- serf/trunk/context.c (original) +++ serf/trunk/context.c Wed Nov 25 10:35:59 2015 @@ -380,6 +380,8 @@ const char *serf_error_string(apr_status return "The stream returned less data than was expected"; case SERF_ERROR_EMPTY_STREAM: return "The stream is empty"; + case SERF_ERROR_EMPTY_READ: + return "A successfull read of nothing occured"; case SERF_ERROR_SSL_COMM_FAILED: return "An error occurred during SSL communication"; Modified: serf/trunk/serf.h URL: http://svn.apache.org/viewvc/serf/trunk/serf.h?rev=1716346&r1=1716345&r2=1716346&view=diff ============================================================================== --- serf/trunk/serf.h (original) +++ serf/trunk/serf.h Wed Nov 25 10:35:59 2015 @@ -111,6 +111,8 @@ typedef struct serf_config_t serf_config #define SERF_ERROR_TRUNCATED_STREAM (SERF_ERROR_START + 13) /* The stream is empty */ #define SERF_ERROR_EMPTY_STREAM (SERF_ERROR_START + 14) +/* An empty read was returned. */ +#define SERF_ERROR_EMPTY_READ (SERF_ERROR_START + 15) /* Http-2 stream errors, mapped into our error range */ #define SERF_ERROR_HTTP2_NO_ERROR (SERF_ERROR_START + 50)