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 |
|