--- server/protocol.c (revision 1808035) +++ server/protocol.c (working copy) @@ -1725,40 +1725,52 @@ * prior to this, and then read the data for this bucket. */ rv = apr_bucket_read(e, &ignored, &len, eblock); + if ((rv != APR_SUCCESS) && !APR_STATUS_IS_EAGAIN(rv)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00574) + "ap_content_length_filter: " + "apr_bucket_read() failed"); + return rv; + } if (rv == APR_SUCCESS) { + /* include just read bucket in flush */ + e = APR_BUCKET_NEXT(e); /* Attempt a nonblocking read next time through */ eblock = APR_NONBLOCK_READ; r->bytes_sent += len; } else if (APR_STATUS_IS_EAGAIN(rv)) { - /* Output everything prior to this bucket, and then - * do a blocking read on the next batch. - */ - if (e != APR_BRIGADE_FIRST(b)) { - apr_bucket *flush; - apr_brigade_split_ex(b, e, ctx->tmpbb); - flush = apr_bucket_flush_create(r->connection->bucket_alloc); + eblock = APR_BLOCK_READ; + } + /* Output everything prior to this bucket, and then + * do a blocking read on the next batch. + */ + if (e != APR_BRIGADE_FIRST(b)) { + /* Note: e could be the brigade sentinel here, in + * which case the split is a noop, and (as desired) + * the entire brigade b will be passed. */ + apr_brigade_split_ex(b, e, ctx->tmpbb); + if (eblock == APR_BLOCK_READ) { + /* If the next read will block, flush first. */ + apr_bucket *flush = apr_bucket_flush_create(f->c->bucket_alloc);; + APR_BRIGADE_INSERT_TAIL(b, flush); - rv = ap_pass_brigade(f->next, b); - if (rv != APR_SUCCESS || f->c->aborted) { - return rv; - } - apr_brigade_cleanup(b); - APR_BRIGADE_CONCAT(b, ctx->tmpbb); - e = APR_BRIGADE_FIRST(b); + } + + rv = ap_pass_brigade(f->next, b); + if (rv != APR_SUCCESS) { + return rv; + } + else if (f->c->aborted) { + return APR_ECONNABORTED; + } + apr_brigade_cleanup(b); + APR_BRIGADE_CONCAT(b, ctx->tmpbb); + e = APR_BRIGADE_FIRST(b); - ctx->data_sent = 1; - } - eblock = APR_BLOCK_READ; - continue; + ctx->data_sent = 1; } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00574) - "ap_content_length_filter: " - "apr_bucket_read() failed"); - return rv; - } + continue; } else { r->bytes_sent += e->length;