comparison src/http/modules/ngx_http_range_filter_module.c @ 6317:29f35e60840b

Slice filter. Splits a request into subrequests, each providing a specific range of response. The variable "$slice_range" must be used to set subrequest range and proper cache key. The directive "slice" sets slice size. The following example splits requests into 1-megabyte cacheable subrequests. server { listen 8000; location / { slice 1m; proxy_cache cache; proxy_cache_key $uri$is_args$args$slice_range; proxy_set_header Range $slice_range; proxy_cache_valid 200 206 1h; proxy_pass http://127.0.0.1:9000; } }
author Roman Arutyunyan <arut@nginx.com>
date Mon, 07 Dec 2015 16:30:48 +0300
parents 8b6fa4842133
children 2cd019520210
comparison
equal deleted inserted replaced
6316:f44de0d12143 6317:29f35e60840b
152 ngx_http_core_loc_conf_t *clcf; 152 ngx_http_core_loc_conf_t *clcf;
153 ngx_http_range_filter_ctx_t *ctx; 153 ngx_http_range_filter_ctx_t *ctx;
154 154
155 if (r->http_version < NGX_HTTP_VERSION_10 155 if (r->http_version < NGX_HTTP_VERSION_10
156 || r->headers_out.status != NGX_HTTP_OK 156 || r->headers_out.status != NGX_HTTP_OK
157 || r != r->main 157 || (r != r->main && !r->subrequest_ranges)
158 || r->headers_out.content_length_n == -1 158 || r->headers_out.content_length_n == -1
159 || !r->allow_ranges) 159 || !r->allow_ranges)
160 { 160 {
161 return ngx_http_next_header_filter(r); 161 return ngx_http_next_header_filter(r);
162 } 162 }
220 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t)); 220 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t));
221 if (ctx == NULL) { 221 if (ctx == NULL) {
222 return NGX_ERROR; 222 return NGX_ERROR;
223 } 223 }
224 224
225 ctx->offset = r->headers_out.content_offset;
226
225 if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t)) 227 if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t))
226 != NGX_OK) 228 != NGX_OK)
227 { 229 {
228 return NGX_ERROR; 230 return NGX_ERROR;
229 } 231 }
271 273
272 static ngx_int_t 274 static ngx_int_t
273 ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx, 275 ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
274 ngx_uint_t ranges) 276 ngx_uint_t ranges)
275 { 277 {
276 u_char *p; 278 u_char *p;
277 off_t start, end, size, content_length, cutoff, cutlim; 279 off_t start, end, size, content_length, cutoff,
278 ngx_uint_t suffix; 280 cutlim;
279 ngx_http_range_t *range; 281 ngx_uint_t suffix;
282 ngx_http_range_t *range;
283 ngx_http_range_filter_ctx_t *mctx;
284
285 if (r != r->main) {
286 mctx = ngx_http_get_module_ctx(r->main,
287 ngx_http_range_body_filter_module);
288 if (mctx) {
289 ctx->ranges = mctx->ranges;
290 return NGX_OK;
291 }
292 }
280 293
281 p = r->headers_in.range->value.data + 6; 294 p = r->headers_in.range->value.data + 6;
282 size = 0; 295 size = 0;
283 content_length = r->headers_out.content_length_n; 296 content_length = r->headers_out.content_length_n;
284 297
392 ngx_http_range_singlepart_header(ngx_http_request_t *r, 405 ngx_http_range_singlepart_header(ngx_http_request_t *r,
393 ngx_http_range_filter_ctx_t *ctx) 406 ngx_http_range_filter_ctx_t *ctx)
394 { 407 {
395 ngx_table_elt_t *content_range; 408 ngx_table_elt_t *content_range;
396 ngx_http_range_t *range; 409 ngx_http_range_t *range;
410
411 if (r != r->main) {
412 return ngx_http_next_header_filter(r);
413 }
397 414
398 content_range = ngx_list_push(&r->headers_out.headers); 415 content_range = ngx_list_push(&r->headers_out.headers);
399 if (content_range == NULL) { 416 if (content_range == NULL) {
400 return NGX_ERROR; 417 return NGX_ERROR;
401 } 418 }
420 range->start, range->end - 1, 437 range->start, range->end - 1,
421 r->headers_out.content_length_n) 438 r->headers_out.content_length_n)
422 - content_range->value.data; 439 - content_range->value.data;
423 440
424 r->headers_out.content_length_n = range->end - range->start; 441 r->headers_out.content_length_n = range->end - range->start;
442 r->headers_out.content_offset = range->start;
425 443
426 if (r->headers_out.content_length) { 444 if (r->headers_out.content_length) {
427 r->headers_out.content_length->hash = 0; 445 r->headers_out.content_length->hash = 0;
428 r->headers_out.content_length = NULL; 446 r->headers_out.content_length = NULL;
429 } 447 }