View | Details | Raw Unified | Return to bug 61222
Collapse All | Expand All

(-)server/protocol.c (-36 / +49 lines)
Lines 1712-1769 Link Here
1712
     */
1712
     */
1713
    e = APR_BRIGADE_FIRST(b);
1713
    e = APR_BRIGADE_FIRST(b);
1714
    while (e != APR_BRIGADE_SENTINEL(b)) {
1714
    while (e != APR_BRIGADE_SENTINEL(b)) {
1715
        apr_status_t rv;
1716
1715
        if (APR_BUCKET_IS_EOS(e)) {
1717
        if (APR_BUCKET_IS_EOS(e)) {
1716
            eos = 1;
1718
            eos = 1;
1717
            break;
1719
            break;
1718
        }
1720
        }
1719
        if (e->length == (apr_size_t)-1) {
1721
1722
        /* For determinate length data buckets and non-FLUSH metadata
1723
         * buckets, count the length and continue. */
1724
        if ((!APR_BUCKET_IS_METADATA(e) && e->length != (apr_size_t)-1)
1725
            || (APR_BUCKET_IS_METADATA(e) && !APR_BUCKET_IS_FLUSH(e))) {
1726
            r->bytes_sent += e->length;
1727
            e = APR_BUCKET_NEXT(e);
1728
            continue;
1729
        }
1730
1731
        /* For indeterminate length data buckets, perform one read. */
1732
        if (!APR_BUCKET_IS_METADATA(e) && e->length == (apr_size_t)-1) {
1720
            apr_size_t len;
1733
            apr_size_t len;
1721
            const char *ignored;
1734
            const char *ignored;
1722
            apr_status_t rv;
1735
        
1723
1724
            /* This is probably a pipe bucket.  Send everything
1725
             * prior to this, and then read the data for this bucket.
1726
             */
1727
            rv = apr_bucket_read(e, &ignored, &len, eblock);
1736
            rv = apr_bucket_read(e, &ignored, &len, eblock);
1737
            if ((rv != APR_SUCCESS) && !APR_STATUS_IS_EAGAIN(rv)) {
1738
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00574)
1739
                              "ap_content_length_filter: "
1740
                              "apr_bucket_read() failed");
1741
                return rv;
1742
            }
1728
            if (rv == APR_SUCCESS) {
1743
            if (rv == APR_SUCCESS) {
1729
                /* Attempt a nonblocking read next time through */
1744
                /* Similar to the case above, the morphed to the HEAP;
1745
                 * continue with the next bucket, but next time a
1746
                 * non-blocking read. */
1730
                eblock = APR_NONBLOCK_READ;
1747
                eblock = APR_NONBLOCK_READ;
1731
                r->bytes_sent += len;
1748
                r->bytes_sent += len;
1749
                e = APR_BUCKET_NEXT(e);
1750
                continue;
1732
            }
1751
            }
1733
            else if (APR_STATUS_IS_EAGAIN(rv)) {
1752
            else if (APR_STATUS_IS_EAGAIN(rv)) {
1734
                /* Output everything prior to this bucket, and then
1735
                 * do a blocking read on the next batch.
1736
                 */
1737
                if (e != APR_BRIGADE_FIRST(b)) {
1738
                    apr_bucket *flush;
1739
                    apr_brigade_split_ex(b, e, ctx->tmpbb);
1740
                    flush = apr_bucket_flush_create(r->connection->bucket_alloc);
1741
1742
                    APR_BRIGADE_INSERT_TAIL(b, flush);
1743
                    rv = ap_pass_brigade(f->next, b);
1744
                    if (rv != APR_SUCCESS || f->c->aborted) {
1745
                        return rv;
1746
                    }
1747
                    apr_brigade_cleanup(b);
1748
                    APR_BRIGADE_CONCAT(b, ctx->tmpbb);
1749
                    e = APR_BRIGADE_FIRST(b);
1750
1751
                    ctx->data_sent = 1;
1752
                }
1753
                eblock = APR_BLOCK_READ;
1753
                eblock = APR_BLOCK_READ;
1754
                continue;
1755
            }
1754
            }
1756
            else {
1757
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00574)
1758
                              "ap_content_length_filter: "
1759
                              "apr_bucket_read() failed");
1760
                return rv;
1761
            }
1762
        }
1755
        }
1763
        else {
1756
1764
            r->bytes_sent += e->length;
1757
        /* If we reach here, pass on everything in the brigade up to
1758
         * this point. */
1759
        apr_brigade_split_ex(b, e, ctx->tmpbb);
1760
        
1761
        if (eblock == APR_BLOCK_READ) {
1762
            /* If the next read will block, flush first. */
1763
            apr_bucket *flush = apr_bucket_flush_create(f->c->bucket_alloc);
1764
            
1765
            APR_BRIGADE_INSERT_TAIL(b, flush);
1765
        }
1766
        }
1766
        e = APR_BUCKET_NEXT(e);
1767
        
1768
        rv = ap_pass_brigade(f->next, b);
1769
        if (rv != APR_SUCCESS) {
1770
            return rv;
1771
        }
1772
        else if (f->c->aborted) {
1773
            return APR_ECONNABORTED;
1774
        }
1775
        apr_brigade_cleanup(b);
1776
        APR_BRIGADE_CONCAT(b, ctx->tmpbb);
1777
        e = APR_BRIGADE_FIRST(b);
1778
        
1779
        ctx->data_sent = 1;
1767
    }
1780
    }
1768
1781
1769
    /* If we've now seen the entire response and it's otherwise
1782
    /* If we've now seen the entire response and it's otherwise

Return to bug 61222