]> granicus.if.org Git - apache/commitdiff
Merge in byteranges
authorJim Jagielski <jim@apache.org>
Thu, 25 Aug 2011 17:38:19 +0000 (17:38 +0000)
committerJim Jagielski <jim@apache.org>
Thu, 25 Aug 2011 17:38:19 +0000 (17:38 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1161661 13f79535-47bb-0310-9956-ffa450edef68

modules/http/byterange_filter.c

index cc665e5efa041ef6b8053203b650037709066031..63e46798f6d1250a4a4498092660836158e32cb5 100644 (file)
@@ -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;
 }