Commit 931c384a authored by Jim Jagielski's avatar Jim Jagielski
Browse files

Merge in byteranges

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1161661 13f79535-47bb-0310-9956-ffa450edef68
parent 380fbe27
Loading
Loading
Loading
Loading
+76 −9
Changes for modules/http/byterange_filter.c: 76 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -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;
    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;
        }
    else {
        /* a multiple range */
        num_ranges = 2;
        
        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;
}