From 4eddc76b623b85ac0d8c03f5548226cc270e0130 Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Thu, 25 Aug 2011 17:38:19 +0000 Subject: [PATCH] Merge in byteranges git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1161661 13f79535-47bb-0310-9956-ffa450edef68 --- modules/http/byterange_filter.c | 87 +++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/modules/http/byterange_filter.c b/modules/http/byterange_filter.c index cc665e5efa..63e46798f6 100644 --- a/modules/http/byterange_filter.c +++ b/modules/http/byterange_filter.c @@ -469,11 +469,14 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, static int ap_set_byterange(request_rec *r) { - const char *range; + const char *range, *or; const char *if_range; const char *match; const char *ct; - int num_ranges; + char *merged, *cur; + int num_ranges = 0; + apr_off_t ostart, oend; + int in_merge = 0; if (r->assbackwards) { return 0; @@ -526,17 +529,81 @@ static int ap_set_byterange(request_rec *r) } } - if (!ap_strchr_c(range, ',')) { - /* a single range */ - num_ranges = 1; - } - else { - /* a multiple range */ - num_ranges = 2; + range += 6; + or = apr_pstrdup(r->pool, range); + merged = apr_pstrdup(r->pool, ""); + while ((cur = ap_getword(r->pool, &range, ','))) { + char *dash; + char *errp; + apr_off_t number, start, end; + + if (!(dash = strchr(cur, '-'))) { + break; + } + + if (dash == cur) { + /* In the form "-5"... leave as is */ + merged = apr_pstrcat(r->pool, merged, (num_ranges++ ? "," : ""), cur, NULL); + continue; + } + *dash++ = '\0'; + if (!*dash) { + /* form "5-" */ + merged = apr_pstrcat(r->pool, merged, (num_ranges++ ? "," : ""), cur, "-", NULL); + continue; + } + /* + * we have #-#, so we need to grab them... we don't bother + * doing this for the #- or -# cases for speed reasons. + * After all, those will be fixed when the filter parses + * the merged range + */ + if (apr_strtoff(&number, cur, &errp, 10) || *errp || number < 0) { + break; + } + start = number; + if (apr_strtoff(&number, dash, &errp, 10) || *errp || number <= 0) { + break; + } + end = number; + if (!in_merge) { + ostart = start; + oend = end; + } + in_merge = 0; + if (start <= ostart) { + ostart = start; + in_merge = 1; + } + if (start > ostart && start < oend) { + in_merge = 1; + } + if ((end-1) >= oend) { + oend = end; + in_merge = 1; + } + if (end > ostart && end < oend) { + in_merge = 1; + } + if (in_merge) { + continue; + } else { + char *nr = apr_psprintf(r->pool, "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT, + ostart, oend); + merged = apr_pstrcat(r->pool, merged, (num_ranges++ ? "," : ""), nr, NULL); + } } + if (in_merge) { + char *nr = apr_psprintf(r->pool, "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT, + ostart, oend); + merged = apr_pstrcat(r->pool, merged, (num_ranges++ ? "," : ""), nr, NULL); + } + r->status = HTTP_PARTIAL_CONTENT; - r->range = range + 6; + r->range = merged; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "Range: %s | %s", or, merged); return num_ranges; } -- 2.49.0