From: Eric Covener Date: Sat, 3 Sep 2011 17:42:56 +0000 (+0000) Subject: backport revisions 1162584, 1164861, 1162587 from trunk: X-Git-Tag: 2.2.21~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f3819fb2d164adffa3c6661a5a680433b61b364;p=thirdparty%2Fapache%2Fhttpd.git backport revisions 1162584, 1164861, 1162587 from trunk: Add MaxRanges directive and limit # of accepted ranges to 200 by default. Submitted By: Eric Covener, Guenter Knauf Reviewed By: covener, fuankg, sf git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1164894 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index ad77029276c..550df4546f5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.21 + *) core: Add MaxRanges directive to control the number of ranges permitted + before returning the entire resource, with a default limit of 200. + [Eric Covener] Changes with Apache 2.2.20 diff --git a/docs/conf/httpd.conf.in b/docs/conf/httpd.conf.in index 3719f9a6803..b524fdd6305 100644 --- a/docs/conf/httpd.conf.in +++ b/docs/conf/httpd.conf.in @@ -349,6 +349,12 @@ DefaultType text/plain #ErrorDocument 402 http://www.example.com/subscription_info.html # +# +# MaxRanges: Maximum number of Ranges in a request before +# returning the entire resource, or 0 for unlimited +# Default setting is to accept 200 Ranges +#MaxRanges 0 + # # EnableMMAP and EnableSendfile: On systems that support it, # memory-mapping or the sendfile syscall is used to deliver diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index 75f49943f16..313501a2891 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -2298,6 +2298,24 @@ connection + +MaxRanges +Number of ranges allowed before returning the complete +resource +MaxRanges number (0 = no limit) +MaxRanges 200 +server configvirtual host +directory + +Available in Apache HTTP Server 2.3.15 and later + + +

The MaxRanges directive + limits the number of HTTP ranges the server is willing to + return to the client. If more ranges then permitted are requested, + the complete resource is returned instead.

+
+
NameVirtualHost diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 58951c0ecfd..50fe52cfcbf 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -146,6 +146,7 @@ * Add core_dir_config.decode_encoded_slashes. * 20051115.28 (2.2.19) Restore ap_unescape_url_keep2f(char *url) signature * altered in 2.2.18. Add ap_unescape_url_keep2f_ex(). + * 20051115.29 (2.2.21) add max_ranges to core_dir_config */ #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ @@ -153,7 +154,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20051115 #endif -#define MODULE_MAGIC_NUMBER_MINOR 28 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 29 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/http_core.h b/include/http_core.h index 0b96cca5aa9..9d78e081b5f 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -570,6 +570,10 @@ typedef struct { unsigned int decode_encoded_slashes : 1; /* whether to decode encoded slashes in URLs */ + + /** Number of Ranges before returning HTTP_OK, 0/unlimited -1/unset. **/ + int max_ranges; + } core_dir_config; /* Per-server core configuration */ diff --git a/modules/http/byterange_filter.c b/modules/http/byterange_filter.c index 6843df1bf89..ffc8287701c 100644 --- a/modules/http/byterange_filter.c +++ b/modules/http/byterange_filter.c @@ -55,6 +55,10 @@ #include #endif +#ifndef DEFAULT_MAX_RANGES +#define DEFAULT_MAX_RANGES 200 +#endif + static int ap_set_byterange(request_rec *r, apr_off_t clength, apr_array_header_t **indexes); @@ -243,6 +247,12 @@ typedef struct indexes_t { apr_off_t end; } indexes_t; +static int get_max_ranges(request_rec *r) { + core_dir_config *core_conf = ap_get_module_config(r->per_dir_config, + &core_module); + return core_conf->max_ranges == -1 ? DEFAULT_MAX_RANGES : core_conf->max_ranges; +} + AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, apr_bucket_brigade *bb) { @@ -263,6 +273,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, indexes_t *idx; int original_status; int i; + int max_ranges = get_max_ranges(r); /* * Iterate through the brigade until reaching EOS or a bucket with @@ -290,7 +301,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, num_ranges = ap_set_byterange(r, clength, &indexes); /* We have nothing to do, get out of the way. */ - if (num_ranges == 0) { + if (num_ranges == 0 || (max_ranges > 0 && num_ranges > max_ranges)) { r->status = original_status; ap_remove_output_filter(f); return ap_pass_brigade(f->next, bb); diff --git a/server/core.c b/server/core.c index ea01ca926d7..d21e2924040 100644 --- a/server/core.c +++ b/server/core.c @@ -165,6 +165,8 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir) conf->enable_sendfile = ENABLE_SENDFILE_UNSET; conf->allow_encoded_slashes = 0; conf->decode_encoded_slashes = 0; + + conf->max_ranges = -1; return (void *)conf; } @@ -453,6 +455,8 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) conf->allow_encoded_slashes = new->allow_encoded_slashes; conf->decode_encoded_slashes = new->decode_encoded_slashes; + conf->max_ranges = new->max_ranges != -1 ? new->max_ranges : base->max_ranges; + return (void*)conf; } @@ -2978,6 +2982,16 @@ static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_, return NULL; } +static const char *set_max_ranges(cmd_parms *cmd, void *conf_, const char *arg) +{ + core_dir_config *conf = conf_; + + conf->max_ranges = atoi(arg); + if (conf->max_ranges < 0) + return "MaxRanges requires a non-negative integer (0 = unlimited)"; + + return NULL; +} AP_DECLARE(size_t) ap_get_limit_xml_body(const request_rec *r) { core_dir_config *conf; @@ -3407,6 +3421,9 @@ AP_INIT_TAKE1("LimitXMLRequestBody", set_limit_xml_req_body, NULL, OR_ALL, "Limit (in bytes) on maximum size of an XML-based request " "body"), +AP_INIT_TAKE1("MaxRanges", set_max_ranges, NULL, RSRC_CONF|ACCESS_CONF, + "Maximum number of Ranges in a request before returning the entire " + "resource, or 0 for unlimited"), /* System Resource Controls */ #ifdef RLIMIT_CPU AP_INIT_TAKE12("RLimitCPU", set_limit_cpu,