From: Ryan Bloom Date: Sun, 17 Dec 2000 18:04:14 +0000 (+0000) Subject: Get byterange requests working with data that is generated by a handler X-Git-Tag: APACHE_2_0_BETA_CANDIDATE_1~420 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b34037db5e6508676eb72b47631175b433459480;p=apache Get byterange requests working with data that is generated by a handler that does not add a content-length. For example, mod_autoindex doesn't set a content-length, but the byterange filter requires one. We fix this by computing the content-length in the byterange filter. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@87389 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 3c8515f62b..11b182d630 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ Changes with Apache 2.0b1 + *) Get byterange requests working with responses that do not have a + content-length. Because of the way byterange requests work, we have to + have all of the data before we can actually do the byterange, so we + can compute the content-length in the byterange filter. + [Ryan Bloom] *) Get exe CGI's working again on Windows. [Allan Edwards] diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index eb4906f5a5..516a80fba0 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -223,6 +223,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter( apr_off_t range_end; char *current; const char *bound_head; + int clength = 0; if (!ctx) { int num_ranges = ap_set_byterange(r); @@ -267,11 +268,26 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter( bb = ctx->bb; ctx->bb = NULL; /* ### strictly necessary? call brigade_destroy? */ + /* It is possible that we won't have a content length yet, so we have to + * compute the length before we can actually do the byterange work. + */ + AP_BRIGADE_FOREACH(e, bb) { + const char *ignore; + apr_size_t len; + + if (e->length >= 0) { + clength += e->length; + continue; + } + ap_bucket_read(e, &ignore, &len, AP_NONBLOCK_READ); + clength += e->length; + } + /* this brigade holds what we will be sending */ bsend = ap_brigade_create(r->pool); while ((current = ap_getword(r->pool, &r->range, ',')) && - parse_byterange(current, r->clength, &range_start, &range_end)) { + parse_byterange(current, clength, &range_start, &range_end)) { const char *str; apr_size_t n; const char *range; @@ -348,7 +364,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter( AP_BRIGADE_INSERT_TAIL(bsend, e); ts = apr_psprintf(r->pool, BYTERANGE_FMT CRLF CRLF, - range_start, range_end, r->clength); + range_start, range_end, clength); e = ap_bucket_create_pool(ts, strlen(ts), r->pool); AP_BRIGADE_INSERT_TAIL(bsend, e); } @@ -2343,8 +2359,7 @@ static int ap_set_byterange(request_rec *r) apr_off_t range_end; int num_ranges; - /* ### this test for r->clength is probably a Bad Thing. need to fix */ - if (!r->clength || r->assbackwards) + if (r->assbackwards) return 0; /* Check for Range request-header (HTTP/1.1) or Request-Range for