comparison src/http/modules/ngx_http_range_filter_module.c @ 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
comparison
equal deleted inserted replaced
4061:bd2ec6ce5d58 4062:82738a316a54
57 ngx_array_t ranges; 57 ngx_array_t ranges;
58 } ngx_http_range_filter_ctx_t; 58 } ngx_http_range_filter_ctx_t;
59 59
60 60
61 static ngx_int_t ngx_http_range_parse(ngx_http_request_t *r, 61 static ngx_int_t ngx_http_range_parse(ngx_http_request_t *r,
62 ngx_http_range_filter_ctx_t *ctx); 62 ngx_http_range_filter_ctx_t *ctx, ngx_uint_t ranges);
63 static ngx_int_t ngx_http_range_singlepart_header(ngx_http_request_t *r, 63 static ngx_int_t ngx_http_range_singlepart_header(ngx_http_request_t *r,
64 ngx_http_range_filter_ctx_t *ctx); 64 ngx_http_range_filter_ctx_t *ctx);
65 static ngx_int_t ngx_http_range_multipart_header(ngx_http_request_t *r, 65 static ngx_int_t ngx_http_range_multipart_header(ngx_http_request_t *r,
66 ngx_http_range_filter_ctx_t *ctx); 66 ngx_http_range_filter_ctx_t *ctx);
67 static ngx_int_t ngx_http_range_not_satisfiable(ngx_http_request_t *r); 67 static ngx_int_t ngx_http_range_not_satisfiable(ngx_http_request_t *r);
144 144
145 static ngx_int_t 145 static ngx_int_t
146 ngx_http_range_header_filter(ngx_http_request_t *r) 146 ngx_http_range_header_filter(ngx_http_request_t *r)
147 { 147 {
148 time_t if_range; 148 time_t if_range;
149 ngx_http_core_loc_conf_t *clcf;
149 ngx_http_range_filter_ctx_t *ctx; 150 ngx_http_range_filter_ctx_t *ctx;
150 151
151 if (r->http_version < NGX_HTTP_VERSION_10 152 if (r->http_version < NGX_HTTP_VERSION_10
152 || r->headers_out.status != NGX_HTTP_OK 153 || r->headers_out.status != NGX_HTTP_OK
153 || r != r->main 154 || r != r->main
155 || !r->allow_ranges) 156 || !r->allow_ranges)
156 { 157 {
157 return ngx_http_next_header_filter(r); 158 return ngx_http_next_header_filter(r);
158 } 159 }
159 160
161 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
162
163 if (clcf->max_ranges == 0) {
164 return ngx_http_next_header_filter(r);
165 }
166
160 if (r->headers_in.range == NULL 167 if (r->headers_in.range == NULL
161 || r->headers_in.range->value.len < 7 168 || r->headers_in.range->value.len < 7
162 || ngx_strncasecmp(r->headers_in.range->value.data, 169 || ngx_strncasecmp(r->headers_in.range->value.data,
163 (u_char *) "bytes=", 6) 170 (u_char *) "bytes=", 6)
164 != 0) 171 != 0)
189 != NGX_OK) 196 != NGX_OK)
190 { 197 {
191 return NGX_ERROR; 198 return NGX_ERROR;
192 } 199 }
193 200
194 switch (ngx_http_range_parse(r, ctx)) { 201 switch (ngx_http_range_parse(r, ctx, clcf->max_ranges)) {
195 202
196 case NGX_OK: 203 case NGX_OK:
197 ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module); 204 ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module);
198 205
199 r->headers_out.status = NGX_HTTP_PARTIAL_CONTENT; 206 r->headers_out.status = NGX_HTTP_PARTIAL_CONTENT;
229 return ngx_http_next_header_filter(r); 236 return ngx_http_next_header_filter(r);
230 } 237 }
231 238
232 239
233 static ngx_int_t 240 static ngx_int_t
234 ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx) 241 ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
242 ngx_uint_t ranges)
235 { 243 {
236 u_char *p; 244 u_char *p;
237 off_t start, end, size, content_length; 245 off_t start, end, size, content_length;
238 ngx_uint_t suffix; 246 ngx_uint_t suffix;
239 ngx_http_range_t *range; 247 ngx_http_range_t *range;
312 320
313 range->start = start; 321 range->start = start;
314 range->end = end; 322 range->end = end;
315 323
316 size += end - start; 324 size += end - start;
325
326 if (--ranges == 0) {
327 break;
328 }
317 } 329 }
318 330
319 if (*p++ != ',') { 331 if (*p++ != ',') {
320 break; 332 break;
321 } 333 }