From 1aaea94cb577002e33f32b8359a0e5b5673ffea6 Mon Sep 17 00:00:00 2001 From: Eric Covener Date: Sun, 28 Aug 2011 20:35:07 +0000 Subject: [PATCH] add MaxRanges directive institute a default limit of 200 (post-merge where applicable) Ranges before returning the complete resource. (minor mmn bump for core_dir_config addition) git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1162584 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ include/ap_mmn.h | 3 ++- include/http_core.h | 3 +++ modules/http/byterange_filter.c | 15 ++++++++++++++- server/core.c | 17 +++++++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index c3587b46b5..5dd40d6d7a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.3.15 + *) core: Add MaxRanges directive to control the number of ranges permitted + before returning the entire resource, with a default limit of 200. + [Eric Covener] + *) mod_cache: Ensure that CacheDisable can correctly appear within a LocationMatch. [Graham Leggett] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index b892e0e48b..e37d874d68 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -348,6 +348,7 @@ * 20110724.1 (2.3.15-dev) add NOT_IN_HTACCESS * 20110724.2 (2.3.15-dev) retries and retry_delay in util_ldap_state_t * 20110724.3 (2.3.15-dev) add util_varbuf.h / ap_varbuf API + * 20110724.4 (2.3.15-dev) add max_ranges to core_dir_config */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -355,7 +356,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20110724 #endif -#define MODULE_MAGIC_NUMBER_MINOR 3 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 4 /* 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 a41cf9b54f..cfd7cf08fb 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -605,6 +605,9 @@ typedef struct { /** Table of directives allowed per AllowOverrideList */ apr_table_t *override_list; + /** Number of Ranges before returning HTTP_OK, 0/unlimited -1/unset. **/ + int max_ranges; + } core_dir_config; /* macro to implement off by default behaviour */ diff --git a/modules/http/byterange_filter.c b/modules/http/byterange_filter.c index d314c60a0d..775d7e7215 100644 --- a/modules/http/byterange_filter.c +++ b/modules/http/byterange_filter.c @@ -59,6 +59,10 @@ #include #endif +#ifndef DEFAULT_MAX_RANGES +#define DEFAULT_MAX_RANGES 200 +#endif + APLOG_USE_MODULE(http); static int ap_set_byterange(request_rec *r, apr_off_t clength, @@ -255,6 +259,11 @@ 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_core_module_config(r->per_dir_config); + 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) { @@ -274,6 +283,8 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, apr_array_header_t *indexes; indexes_t *idx; int i; + int original_status; + int max_ranges = get_max_ranges(r); /* * Iterate through the brigade until reaching EOS or a bucket with @@ -297,10 +308,12 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, return ap_pass_brigade(f->next, bb); } + original_status = r->status; 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 14b401b587..a6ac9c11ef 100644 --- a/server/core.c +++ b/server/core.c @@ -178,6 +178,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; } @@ -397,6 +399,8 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) } } + conf->max_ranges = new->max_ranges != -1 ? new->max_ranges : base->max_ranges; + return (void*)conf; } @@ -3260,6 +3264,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; @@ -3876,6 +3890,9 @@ AP_INIT_TAKE1("LimitXMLRequestBody", set_limit_xml_req_body, NULL, OR_ALL, AP_INIT_RAW_ARGS("Mutex", ap_set_mutex, NULL, RSRC_CONF, "mutex (or \"default\") and mechanism"), +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, -- 2.50.1