httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r1167263 - /httpd/httpd/trunk/modules/http/byterange_filter.c
Date Fri, 09 Sep 2011 16:02:18 GMT
Author: jim
Date: Fri Sep  9 16:02:18 2011
New Revision: 1167263

URL: http://svn.apache.org/viewvc?rev=1167263&view=rev
Log:
No reason for the advanced def...
Open hook for other conf factors (number of overlaps, etc)...
Return some range params...

Modified:
    httpd/httpd/trunk/modules/http/byterange_filter.c

Modified: httpd/httpd/trunk/modules/http/byterange_filter.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http/byterange_filter.c?rev=1167263&r1=1167262&r2=1167263&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http/byterange_filter.c (original)
+++ httpd/httpd/trunk/modules/http/byterange_filter.c Fri Sep  9 16:02:18 2011
@@ -59,10 +59,232 @@
 #define AP_DEFAULT_MAX_RANGES 200
 #endif
 
+#define MAX_PREALLOC_RANGES 100
+
 APLOG_USE_MODULE(http);
 
+typedef struct indexes_t {
+    apr_off_t start;
+    apr_off_t end;
+} indexes_t;
+
+/*
+ * returns number of ranges OR -1 if unsatisfiable
+ */
 static int ap_set_byterange(request_rec *r, apr_off_t clength,
-                            apr_array_header_t **indexes);
+                            apr_array_header_t **indexes, int *overlaps,
+                            int *reversals)
+{
+    const char *range;
+    const char *if_range;
+    const char *match;
+    const char *ct;
+    char *cur, **new;
+    apr_array_header_t *merged;
+    int num_ranges = 0, unsatisfiable = 0;
+    apr_off_t ostart = 0, oend = 0, sum_lengths = 0;
+    int in_merge = 0;
+    indexes_t *idx;
+    int ranges = 1;
+    const char *it;
+
+    *overlaps = 0;
+    *reversals = 0;
+    if (r->assbackwards) {
+        return 0;
+    }
+
+    /*
+     * Check for Range request-header (HTTP/1.1) or Request-Range for
+     * backwards-compatibility with second-draft Luotonen/Franks
+     * byte-ranges (e.g. Netscape Navigator 2-3).
+     *
+     * We support this form, with Request-Range, and (farther down) we
+     * send multipart/x-byteranges instead of multipart/byteranges for
+     * Request-Range based requests to work around a bug in Netscape
+     * Navigator 2-3 and MSIE 3.
+     */
+
+    if (!(range = apr_table_get(r->headers_in, "Range"))) {
+        range = apr_table_get(r->headers_in, "Request-Range");
+    }
+
+    if (!range || strncasecmp(range, "bytes=", 6) || r->status != HTTP_OK) {
+        return 0;
+    }
+
+    /* is content already a single range? */
+    if (apr_table_get(r->headers_out, "Content-Range")) {
+        return 0;
+    }
+
+    /* is content already a multiple range? */
+    if ((ct = apr_table_get(r->headers_out, "Content-Type"))
+        && (!strncasecmp(ct, "multipart/byteranges", 20)
+            || !strncasecmp(ct, "multipart/x-byteranges", 22))) {
+            return 0;
+        }
+
+    /*
+     * Check the If-Range header for Etag or Date.
+     * Note that this check will return false (as required) if either
+     * of the two etags are weak.
+     */
+    if ((if_range = apr_table_get(r->headers_in, "If-Range"))) {
+        if (if_range[0] == '"') {
+            if (!(match = apr_table_get(r->headers_out, "Etag"))
+                || (strcmp(if_range, match) != 0)) {
+                return 0;
+            }
+        }
+        else if (!(match = apr_table_get(r->headers_out, "Last-Modified"))
+                 || (strcmp(if_range, match) != 0)) {
+            return 0;
+        }
+    }
+
+    range += 6;
+    it = range;
+    while (*it) {
+        if (*it++ == ',') {
+            ranges++;
+        }
+    }
+    it = range;
+    if (ranges > MAX_PREALLOC_RANGES) {
+        ranges = MAX_PREALLOC_RANGES;
+    }
+    *indexes = apr_array_make(r->pool, ranges, sizeof(indexes_t));
+    merged = apr_array_make(r->pool, ranges, sizeof(char *));
+    while ((cur = ap_getword(r->pool, &range, ','))) {
+        char *dash;
+        char *errp;
+        apr_off_t number, start, end;
+
+        if (!*cur)
+            break;
+
+        /*
+         * Per RFC 2616 14.35.1: If there is at least one syntactically invalid
+         * byte-range-spec, we must ignore the whole header.
+         */
+
+        if (!(dash = strchr(cur, '-'))) {
+            return 0;
+        }
+
+        if (dash == cur) {
+            /* In the form "-5" */
+            if (apr_strtoff(&number, dash+1, &errp, 10) || *errp) {
+                return 0;
+            }
+            if (number < 1) {
+                return 0;
+            }
+            start = clength - number;
+            end = clength - 1;
+        }
+        else {
+            *dash++ = '\0';
+            if (apr_strtoff(&number, cur, &errp, 10) || *errp) {
+                return 0;
+            }
+            start = number;
+            if (*dash) {
+                if (apr_strtoff(&number, dash, &errp, 10) || *errp) {
+                    return 0;
+                }
+                end = number;
+                if (start > end) {
+                    return 0;
+                }
+            }
+            else {                  /* "5-" */
+                end = clength - 1;
+            }
+        }
+
+        if (start < 0) {
+            start = 0;
+        }
+        if (start >= clength) {
+            unsatisfiable = 1;
+            continue;
+        }
+        if (end >= clength) {
+            end = clength - 1;
+        }
+
+        if (!in_merge) {
+            /* new set */
+            ostart = start;
+            oend = end;
+            in_merge = 1;
+            continue;
+        }
+        in_merge = 0;
+
+        if (start >= ostart && end <= oend) {
+            in_merge = 1;
+        }
+
+        if (start < ostart && end >= ostart-1) {
+            ostart = start;
+            (*reversals)++;
+            in_merge = 1;
+        }
+        if (end >= oend && start <= oend+1 ) {
+            oend = end;
+            in_merge = 1;
+        }
+
+        if (in_merge) {
+            (*overlaps)++;
+            continue;
+        } else {
+            new = (char **)apr_array_push(merged);
+            *new = apr_psprintf(r->pool, "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT,
+                                ostart, oend);
+            idx = (indexes_t *)apr_array_push(*indexes);
+            idx->start = ostart;
+            idx->end = oend;
+            sum_lengths += oend - ostart + 1;
+            /* new set again */
+            in_merge = 1;
+            ostart = start;
+            oend = end;
+            num_ranges++;
+        }
+    }
+
+    if (in_merge) {
+        new = (char **)apr_array_push(merged);
+        *new = apr_psprintf(r->pool, "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT,
+                            ostart, oend);
+        idx = (indexes_t *)apr_array_push(*indexes);
+        idx->start = ostart;
+        idx->end = oend;
+        sum_lengths += oend - ostart + 1;
+        num_ranges++;
+    }
+    else if (num_ranges == 0 && unsatisfiable) {
+        /* If all ranges are unsatisfiable, we should return 416 */
+        return -1;
+    }
+    if (sum_lengths >= clength) {
+        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+                      "Sum of ranges not smaller than file, ignoring.");
+        return 0;
+    }
+
+    r->status = HTTP_PARTIAL_CONTENT;
+    r->range = apr_array_pstrcat(r->pool, merged, ',');
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+                  "Range: %s | %s (%d : %d : %"APR_OFF_T_FMT")",
+                  it, r->range, *overlaps, *reversals, clength);
+
+    return num_ranges;
+}
 
 /*
  * Here we try to be compatible with clients that want multipart/x-byteranges
@@ -80,7 +302,6 @@ static int use_range_x(request_rec *r)
 }
 
 #define BYTERANGE_FMT "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT "/%" APR_OFF_T_FMT
-#define MAX_PREALLOC_RANGES 100
 
 static apr_status_t copy_brigade_range(apr_bucket_brigade *bb,
                                        apr_bucket_brigade *bbout,
@@ -181,12 +402,7 @@ static apr_status_t copy_brigade_range(a
     return APR_SUCCESS;
 }
 
-typedef struct indexes_t {
-    apr_off_t start;
-    apr_off_t end;
-} indexes_t;
-
-static int get_max_ranges(request_rec *r) { 
+static int get_max_ranges(request_rec *r) {
     core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config);
     if (core_conf->max_ranges >= 0 || core_conf->max_ranges == AP_MAXRANGES_UNLIMITED)
{ 
         return core_conf->max_ranges;
@@ -230,8 +446,12 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
     indexes_t *idx;
     int i;
     int original_status;
-    int max_ranges = get_max_ranges(r);
+    int overlaps = 0;
+    int reversals = 0;
+    int max_ranges;
+    core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config);
 
+    max_ranges = (core_conf->max_ranges == -1 ? DEFAULT_MAX_RANGES : core_conf->max_ranges);
     /*
      * Iterate through the brigade until reaching EOS or a bucket with
      * unknown length.
@@ -255,7 +475,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
     }
 
     original_status = r->status;
-    num_ranges = ap_set_byterange(r, clength, &indexes);
+    num_ranges = ap_set_byterange(r, clength, &indexes, &overlaps, &reversals);
 
     /* We have nothing to do, get out of the way. */
     if (num_ranges == 0 || (max_ranges >= 0 && num_ranges > max_ranges)) {
@@ -381,215 +601,3 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
     return ap_pass_brigade(f->next, bsend);
 }
 
-static int ap_set_byterange(request_rec *r, apr_off_t clength,
-                            apr_array_header_t **indexes)
-{
-    const char *range;
-    const char *if_range;
-    const char *match;
-    const char *ct;
-    char *cur, **new;
-    apr_array_header_t *merged;
-    int num_ranges = 0, unsatisfiable = 0;
-    apr_off_t ostart = 0, oend = 0, sum_lengths = 0;
-    int in_merge = 0;
-    indexes_t *idx;
-    int overlaps = 0, reversals = 0;
-    int ranges = 1;
-    const char *it;
-
-    if (r->assbackwards) {
-        return 0;
-    }
-
-    /*
-     * Check for Range request-header (HTTP/1.1) or Request-Range for
-     * backwards-compatibility with second-draft Luotonen/Franks
-     * byte-ranges (e.g. Netscape Navigator 2-3).
-     *
-     * We support this form, with Request-Range, and (farther down) we
-     * send multipart/x-byteranges instead of multipart/byteranges for
-     * Request-Range based requests to work around a bug in Netscape
-     * Navigator 2-3 and MSIE 3.
-     */
-
-    if (!(range = apr_table_get(r->headers_in, "Range"))) {
-        range = apr_table_get(r->headers_in, "Request-Range");
-    }
-
-    if (!range || strncasecmp(range, "bytes=", 6) || r->status != HTTP_OK) {
-        return 0;
-    }
-
-    /* is content already a single range? */
-    if (apr_table_get(r->headers_out, "Content-Range")) {
-       return 0;
-    }
-
-    /* is content already a multiple range? */
-    if ((ct = apr_table_get(r->headers_out, "Content-Type"))
-        && (!strncasecmp(ct, "multipart/byteranges", 20)
-            || !strncasecmp(ct, "multipart/x-byteranges", 22))) {
-       return 0;
-    }
-
-    /*
-     * Check the If-Range header for Etag or Date.
-     * Note that this check will return false (as required) if either
-     * of the two etags are weak.
-     */
-    if ((if_range = apr_table_get(r->headers_in, "If-Range"))) {
-        if (if_range[0] == '"') {
-            if (!(match = apr_table_get(r->headers_out, "Etag"))
-                || (strcmp(if_range, match) != 0)) {
-                return 0;
-            }
-        }
-        else if (!(match = apr_table_get(r->headers_out, "Last-Modified"))
-                 || (strcmp(if_range, match) != 0)) {
-            return 0;
-        }
-    }
-
-    range += 6;
-    it = range;
-    while (*it) {
-        if (*it++ == ',') {
-            ranges++;
-        }
-    }
-    it = range;
-    if (ranges > MAX_PREALLOC_RANGES) {
-        ranges = MAX_PREALLOC_RANGES;
-    }
-    *indexes = apr_array_make(r->pool, ranges, sizeof(indexes_t));
-    merged = apr_array_make(r->pool, ranges, sizeof(char *));
-    while ((cur = ap_getword(r->pool, &range, ','))) {
-        char *dash;
-        char *errp;
-        apr_off_t number, start, end;
-
-        if (!*cur)
-            break;
-
-        /*
-         * Per RFC 2616 14.35.1: If there is at least one syntactically invalid
-         * byte-range-spec, we must ignore the whole header.
-         */
-
-        if (!(dash = strchr(cur, '-'))) {
-            return 0;
-        }
-
-        if (dash == cur) {
-            /* In the form "-5" */
-            if (apr_strtoff(&number, dash+1, &errp, 10) || *errp) {
-                return 0;
-            }
-            if (number < 1) {
-                return 0;
-            }
-            start = clength - number;
-            end = clength - 1;
-        }
-        else {
-            *dash++ = '\0';
-            if (apr_strtoff(&number, cur, &errp, 10) || *errp) {
-                return 0;
-            }
-            start = number;
-            if (*dash) {
-                if (apr_strtoff(&number, dash, &errp, 10) || *errp) {
-                    return 0;
-                }
-                end = number;
-                if (start > end) {
-                    return 0;
-                }
-            }
-            else {                  /* "5-" */
-                end = clength - 1;
-            }
-        }
-
-        if (start < 0) {
-            start = 0;
-        }
-        if (start >= clength) {
-            unsatisfiable = 1;
-            continue;
-        }
-        if (end >= clength) {
-            end = clength - 1;
-        }
-
-        if (!in_merge) {
-            /* new set */
-            ostart = start;
-            oend = end;
-            in_merge = 1;
-            continue;
-        }
-        in_merge = 0;
-
-        if (start >= ostart && end <= oend) {
-            in_merge = 1;
-        }
-
-        if (start < ostart && end >= ostart-1) {
-            ostart = start;
-            reversals++;
-            in_merge = 1;
-        }
-        if (end >= oend && start <= oend+1 ) {
-            oend = end;
-            in_merge = 1;
-        }
-
-        if (in_merge) {
-            overlaps++;
-            continue;
-        } else {
-            new = (char **)apr_array_push(merged);
-            *new = apr_psprintf(r->pool, "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT,
-                                    ostart, oend);
-            idx = (indexes_t *)apr_array_push(*indexes);
-            idx->start = ostart;
-            idx->end = oend;
-            sum_lengths += oend - ostart + 1;
-            /* new set again */
-            in_merge = 1;
-            ostart = start;
-            oend = end;
-            num_ranges++;
-        }
-    }
-
-    if (in_merge) {
-        new = (char **)apr_array_push(merged);
-        *new = apr_psprintf(r->pool, "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT,
-                            ostart, oend);
-        idx = (indexes_t *)apr_array_push(*indexes);
-        idx->start = ostart;
-        idx->end = oend;
-        sum_lengths += oend - ostart + 1;
-        num_ranges++;
-    }
-    else if (num_ranges == 0 && unsatisfiable) {
-        /* If all ranges are unsatisfiable, we should return 416 */
-        return -1;
-    }
-    if (sum_lengths >= clength) {
-        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
-                      "Sum of ranges not smaller than file, ignoring.");
-        return 0;
-    }
-
-    r->status = HTTP_PARTIAL_CONTENT;
-    r->range = apr_array_pstrcat(r->pool, merged, ',');
-    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-                  "Range: %s | %s (%d : %d : %"APR_OFF_T_FMT")",
-                  it, r->range, overlaps, reversals, clength);
-
-    return num_ranges;
-}



Mime
View raw message