changeset 4062:82738a316a54

The "max_ranges" directive. "max_ranges 0" disables ranges support at all, "max_ranges 1" allows the single range, etc. By default number of ranges is unlimited, to be precise, 2^31-1.
author Igor Sysoev <igor@sysoev.ru>
date Wed, 31 Aug 2011 09:40:55 +0000
parents bd2ec6ce5d58
children 8d70904b6c48
files src/http/modules/ngx_http_range_filter_module.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h
diffstat 3 files changed, 26 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/modules/ngx_http_range_filter_module.c
+++ b/src/http/modules/ngx_http_range_filter_module.c
@@ -59,7 +59,7 @@ typedef struct {
 
 
 static ngx_int_t ngx_http_range_parse(ngx_http_request_t *r,
-    ngx_http_range_filter_ctx_t *ctx);
+    ngx_http_range_filter_ctx_t *ctx, ngx_uint_t ranges);
 static ngx_int_t ngx_http_range_singlepart_header(ngx_http_request_t *r,
     ngx_http_range_filter_ctx_t *ctx);
 static ngx_int_t ngx_http_range_multipart_header(ngx_http_request_t *r,
@@ -146,6 +146,7 @@ static ngx_int_t
 ngx_http_range_header_filter(ngx_http_request_t *r)
 {
     time_t                        if_range;
+    ngx_http_core_loc_conf_t     *clcf;
     ngx_http_range_filter_ctx_t  *ctx;
 
     if (r->http_version < NGX_HTTP_VERSION_10
@@ -157,6 +158,12 @@ ngx_http_range_header_filter(ngx_http_re
         return ngx_http_next_header_filter(r);
     }
 
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (clcf->max_ranges == 0) {
+        return ngx_http_next_header_filter(r);
+    }
+
     if (r->headers_in.range == NULL
         || r->headers_in.range->value.len < 7
         || ngx_strncasecmp(r->headers_in.range->value.data,
@@ -191,7 +198,7 @@ ngx_http_range_header_filter(ngx_http_re
         return NGX_ERROR;
     }
 
-    switch (ngx_http_range_parse(r, ctx)) {
+    switch (ngx_http_range_parse(r, ctx, clcf->max_ranges)) {
 
     case NGX_OK:
         ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module);
@@ -231,7 +238,8 @@ next_filter:
 
 
 static ngx_int_t
-ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx)
+ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
+    ngx_uint_t ranges)
 {
     u_char            *p;
     off_t              start, end, size, content_length;
@@ -314,6 +322,10 @@ ngx_http_range_parse(ngx_http_request_t 
             range->end = end;
 
             size += end - start;
+
+            if (--ranges == 0) {
+                break;
+            }
         }
 
         if (*p++ != ',') {
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -631,6 +631,13 @@ static ngx_command_t  ngx_http_core_comm
       offsetof(ngx_http_core_loc_conf_t, if_modified_since),
       &ngx_http_core_if_modified_since },
 
+    { ngx_string("max_ranges"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, max_ranges),
+      NULL },
+
     { ngx_string("chunked_transfer_encoding"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_flag_slot,
@@ -3253,6 +3260,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t
     clcf->keepalive_disable = NGX_CONF_UNSET_UINT;
     clcf->satisfy = NGX_CONF_UNSET_UINT;
     clcf->if_modified_since = NGX_CONF_UNSET_UINT;
+    clcf->max_ranges = NGX_CONF_UNSET_UINT;
     clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
     clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
     clcf->internal = NGX_CONF_UNSET;
@@ -3459,6 +3467,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
                               NGX_HTTP_SATISFY_ALL);
     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
                               NGX_HTTP_IMS_EXACT);
+    ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges,
+                              0x7fffffff);
     ngx_conf_merge_uint_value(conf->client_body_in_file_only,
                               prev->client_body_in_file_only, 0);
     ngx_conf_merge_value(conf->client_body_in_single_buffer,
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -363,6 +363,7 @@ struct ngx_http_core_loc_conf_s {
     ngx_uint_t    satisfy;                 /* satisfy */
     ngx_uint_t    lingering_close;         /* lingering_close */
     ngx_uint_t    if_modified_since;       /* if_modified_since */
+    ngx_uint_t    max_ranges;              /* max_ranges */
     ngx_uint_t    client_body_in_file_only; /* client_body_in_file_only */
 
     ngx_flag_t    client_body_in_single_buffer;