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

(-)modules/http/http_protocol.c (-27 / +21 lines)
Lines 2856-2873 Link Here
2856
#define MIN_LENGTH(len1, len2) ((len1 > len2) ? len2 : len1)
2856
#define MIN_LENGTH(len1, len2) ((len1 > len2) ? len2 : len1)
2857
    request_rec *r = f->r;
2857
    request_rec *r = f->r;
2858
    conn_rec *c = r->connection;
2858
    conn_rec *c = r->connection;
2859
    byterange_ctx *ctx = f->ctx;
2859
    byterange_ctx *ctx;
2860
    apr_bucket *e;
2860
    apr_bucket *e;
2861
    apr_bucket_brigade *bsend;
2861
    apr_bucket_brigade *bsend;
2862
    apr_off_t range_start;
2862
    apr_off_t range_start;
2863
    apr_off_t range_end;
2863
    apr_off_t range_end;
2864
    char *current;
2864
    char *current;
2865
    apr_off_t bb_length;
2866
    apr_off_t clength = 0;
2865
    apr_off_t clength = 0;
2867
    apr_status_t rv;
2866
    apr_status_t rv;
2868
    int found = 0;
2867
    int found = 0;
2869
2868
2870
    if (!ctx) {
2869
    /* Iterate through the brigade until reaching EOS or a bucket with
2870
     * unknown length. */
2871
    for (e = APR_BRIGADE_FIRST(bb);
2872
         (e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e)
2873
          && e->length != (apr_size_t)-1);
2874
         e = APR_BUCKET_NEXT(e)) {
2875
        clength += e->length;
2876
    }
2877
2878
    /* Don't attempt to do byte range work if this brigade doesn't
2879
     * contain an EOS, or if any of the buckets has an unknown length;
2880
     * this avoids the cases where it is expensive to perform
2881
     * byteranging (i.e. may require arbitrary amounts of memory). */
2882
    if (!APR_BUCKET_IS_EOS(e) || clength <= 0) {
2883
        ap_remove_output_filter(f);
2884
        return ap_pass_brigade(f->next, bb);
2885
    }
2886
2887
    {
2871
        int num_ranges = ap_set_byterange(r);
2888
        int num_ranges = ap_set_byterange(r);
2872
2889
2873
        /* We have nothing to do, get out of the way. */
2890
        /* We have nothing to do, get out of the way. */
Lines 2876-2882 Link Here
2876
            return ap_pass_brigade(f->next, bb);
2893
            return ap_pass_brigade(f->next, bb);
2877
        }
2894
        }
2878
2895
2879
        ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
2896
        ctx = apr_pcalloc(r->pool, sizeof(*ctx));
2880
        ctx->num_ranges = num_ranges;
2897
        ctx->num_ranges = num_ranges;
2881
        /* create a brigade in case we never call ap_save_brigade() */
2898
        /* create a brigade in case we never call ap_save_brigade() */
2882
        ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc);
2899
        ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc);
Lines 2903-2931 Link Here
2903
        }
2920
        }
2904
    }
2921
    }
2905
2922
2906
    /* We can't actually deal with byte-ranges until we have the whole brigade
2907
     * because the byte-ranges can be in any order, and according to the RFC,
2908
     * we SHOULD return the data in the same order it was requested.
2909
     *
2910
     * XXX: We really need to dump all bytes prior to the start of the earliest
2911
     * range, and only slurp up to the end of the latest range.  By this we
2912
     * mean that we should peek-ahead at the lowest first byte of any range,
2913
     * and the highest last byte of any range.
2914
     */
2915
    if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
2916
        ap_save_brigade(f, &ctx->bb, &bb, r->pool);
2917
        return APR_SUCCESS;
2918
    }
2919
2920
    /* Prepend any earlier saved brigades. */
2921
    APR_BRIGADE_PREPEND(bb, ctx->bb);
2922
2923
    /* It is possible that we won't have a content length yet, so we have to
2924
     * compute the length before we can actually do the byterange work.
2925
     */
2926
    apr_brigade_length(bb, 1, &bb_length);
2927
    clength = (apr_off_t)bb_length;
2928
2929
    /* this brigade holds what we will be sending */
2923
    /* this brigade holds what we will be sending */
2930
    bsend = apr_brigade_create(r->pool, c->bucket_alloc);
2924
    bsend = apr_brigade_create(r->pool, c->bucket_alloc);
2931
2925

Return to bug 29962