is enabled, could allow local users to gain privileges via a .htaccess
file. [Stefan Fritsch, Greg Ames]
+ *) core: Add MaxRanges directive to control the number of ranges permitted
+ before returning the entire resource, with a default limit of 200.
+ [Eric Covener, Rainer Jung]
+
+ *) Set 'Accept-Ranges: none' in the case Ranges are being ignored with
+ MaxRanges none. [Eric Covener, Rainer Jung]
+
*) mod_rewrite: Allow merging RewriteBase down to subdirectories
if new option 'RewriteOptions MergeBase' is configured.
[Eric Covener]
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * byterange: Backport MaxRanges configuration directive and
- ap_set_accept_ranges() utility function.
- Trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1162584
- http://svn.apache.org/viewvc?view=revision&revision=1162584
- http://svn.apache.org/viewvc?view=revision&revision=1162587
- http://svn.apache.org/viewvc?view=revision&revision=1166282
- http://svn.apache.org/viewvc?view=revision&revision=1166663
- http://svn.apache.org/viewvc?view=revision&revision=1166667
- 2.2.x patch: http://svn.apache.org/viewvc?view=revision&revision=1164894
- http://svn.apache.org/viewvc?view=revision&revision=1164896
- http://svn.apache.org/viewvc?view=revision&revision=1166612
- http://svn.apache.org/viewvc?view=revision&revision=1166772
- 2.0.x patch: http://people.apache.org/~rjung/patches/max-ranges-2.0.patch
- +1: rjung, wrowe, covener
-
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
[ please place SVN revisions from trunk here, so it is easy to
#
HostnameLookups Off
+#
+# MaxRanges: Maximum number of Ranges in a request before
+# returning the entire resource, or one of the special
+# values 'default', 'none' or 'unlimited'.
+# Default setting is to accept 200 Ranges.
+#MaxRanges unlimited
+
#
# EnableMMAP: Control whether memory-mapping is used to deliver
# files (assuming that the underlying OS supports it).
#
HostnameLookups Off
+#
+# MaxRanges: Maximum number of Ranges in a request before
+# returning the entire resource, or one of the special
+# values 'default', 'none' or 'unlimited'.
+# Default setting is to accept 200 Ranges.
+#MaxRanges unlimited
+
#
# EnableMMAP: Control whether memory-mapping is used to deliver
# files (assuming that the underlying OS supports it).
</usage>
</directivesynopsis>
+<directivesynopsis>
+<name>MaxRanges</name>
+<description>Number of ranges allowed before returning the complete
+resource </description>
+<syntax>MaxRanges default | unlimited | none | <var>number-of-ranges</var></syntax>
+<default>MaxRanges 200</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context>
+</contextlist>
+<compatibility>Available in Apache HTTP Server 2.0.65 and later</compatibility>
+
+<usage>
+ <p>The <directive>MaxRanges</directive> 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.</p>
+
+ <dl>
+ <dt><strong>default</strong></dt>
+ <dd>Limits the number of ranges to a compile-time default of 200.</dd>
+
+ <dt><strong>none</strong></dt>
+ <dd>Range headers are ignored.</dd>
+
+ <dt><strong>unlimited</strong></dt>
+ <dd>The server does not limit the number of ranges it is
+ willing to satisfy.</dd>
+
+ <dt><var>number-of-ranges</var></dt>
+ <dd>A positive number representing the maximum number of ranges the
+ server is willing to satisfy.</dd>
+ </dl>
+</usage>
+</directivesynopsis>
+
<directivesynopsis>
<name>NameVirtualHost</name>
<description>Designates an IP address for name-virtual
* 20020903.14 (2.0.64-dev) added ap_vhost_iterate_given_conn
* 20020903.15 (2.0.65-dev) added state_set, options_set, baseurl_set to
* rewrite_server_conf and rewrite_perdir_conf
+ * 20020903.16 (2.0.65) add max_ranges to core_dir_config and add
+ * ap_set_accept_ranges()
*/
#define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20020903
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 15 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 16 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
unsigned int enable_sendfile : 2; /* files in this dir can be mmap'ed */
unsigned int allow_encoded_slashes : 1; /* URLs may contain %2f w/o being
* pitched indiscriminately */
+#define AP_MAXRANGES_UNSET -1
+#define AP_MAXRANGES_DEFAULT -2
+#define AP_MAXRANGES_UNLIMITED -3
+#define AP_MAXRANGES_NORANGES 0
+ /** Number of Ranges before returning HTTP_OK. **/
+ int max_ranges;
+
} core_dir_config;
/* Per-server core configuration */
*/
AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct);
+/**
+ * Set the Accept-Ranges header for this response
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_set_accept_ranges(request_rec *r);
+
+
/* Hmmm... could macrofy these for now, and maybe forever, though the
* definitions of the macros would get a whole lot hairier.
*/
ap_set_etag(r);
/* we accept byte-ranges */
- apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");
+ ap_set_accept_ranges(r);
/* set up the Content-Length header */
ap_set_content_length(r, resource->info->finfo.size);
return OK;
}
+AP_DECLARE(void) ap_set_accept_ranges(request_rec *r)
+{
+ core_dir_config *d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
+ &core_module);
+ apr_table_setn(r->headers_out, "Accept-Ranges",
+ (d->max_ranges == AP_MAXRANGES_NORANGES) ? "none"
+ : "bytes");
+}
static const char *add_optional_notes(request_rec *r,
const char *prefix,
const char *key,
apr_off_t end;
} indexes_t;
+static int get_max_ranges(request_rec *r) {
+ core_dir_config *core_conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
+ &core_module);
+ if (core_conf->max_ranges >= 0 || core_conf->max_ranges == AP_MAXRANGES_UNLIMITED) {
+ return core_conf->max_ranges;
+ }
+
+ /* Any other negative val means the default */
+ return AP_DEFAULT_MAX_RANGES;
+}
+
static apr_status_t send_416(ap_filter_t *f, apr_bucket_brigade *tmpbb)
{
apr_bucket *e;
apr_array_header_t *indexes;
indexes_t *idx;
int original_status;
+ int max_ranges = get_max_ranges(r);
int i;
/*
num_ranges = ap_set_byterange(r, clength, &indexes);
/* We have nothing to do, get out of the way. */
- if (num_ranges == 0 || (AP_DEFAULT_MAX_RANGES >= 0 && num_ranges > AP_DEFAULT_MAX_RANGES)) {
+ 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);
* ap_set_last_modified(r);
* ap_set_etag(r);
*/
- apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");
+ ap_set_accept_ranges(r);
ap_set_content_length(r, best->bytes);
/* set MIME type and charset as negotiated */
conf->enable_sendfile = ENABLE_SENDFILE_UNSET;
conf->allow_encoded_slashes = 0;
+ conf->max_ranges = AP_MAXRANGES_UNSET;
+
return (void *)conf;
}
}
conf->allow_encoded_slashes = new->allow_encoded_slashes;
-
+
+ conf->max_ranges = new->max_ranges != AP_MAXRANGES_UNSET ? new->max_ranges : base->max_ranges;
+
return (void*)conf;
}
return NULL;
}
+static const char *set_max_ranges(cmd_parms *cmd, void *conf_, const char *arg)
+{
+ core_dir_config *conf = conf_;
+ int val = 0;
+
+ if (!strcasecmp(arg, "none")) {
+ val = AP_MAXRANGES_NORANGES;
+ }
+ else if (!strcasecmp(arg, "default")) {
+ val = AP_MAXRANGES_DEFAULT;
+ }
+ else if (!strcasecmp(arg, "unlimited")) {
+ val = AP_MAXRANGES_UNLIMITED;
+ }
+ else {
+ val = atoi(arg);
+ if (val <= 0)
+ return "MaxRanges requires 'none', 'default', 'unlimited' or "
+ "a positive integer";
+ }
+
+ conf->max_ranges = val;
+
+ return NULL;
+}
+
AP_DECLARE(size_t) ap_get_limit_xml_body(const request_rec *r)
{
core_dir_config *conf;
"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,
ap_update_mtime(r, r->finfo.mtime);
ap_set_last_modified(r);
ap_set_etag(r);
- apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");
+ ap_set_accept_ranges(r);
ap_set_content_length(r, r->finfo.size);
if ((errstatus = ap_meets_conditions(r)) != OK) {
apr_file_close(fd);