comparison src/http/modules/ngx_http_range_filter_module.c @ 963:78e70dae89f0

move ranges array to ngx_http_range_filter_ctx_t
author Igor Sysoev <igor@sysoev.ru>
date Fri, 29 Dec 2006 08:02:31 +0000
parents 69754fb59ba1
children d0fb2cc2a098
comparison
equal deleted inserted replaced
962:69754fb59ba1 963:78e70dae89f0
43 * "--0123456789--" CRLF 43 * "--0123456789--" CRLF
44 */ 44 */
45 45
46 46
47 typedef struct { 47 typedef struct {
48 off_t offset; 48 off_t start;
49 ngx_str_t boundary_header; 49 off_t end;
50 ngx_str_t content_range;
51 } ngx_http_range_t;
52
53
54 typedef struct {
55 off_t offset;
56 ngx_str_t boundary_header;
57 ngx_array_t ranges;
50 } ngx_http_range_filter_ctx_t; 58 } ngx_http_range_filter_ctx_t;
51 59
52 60
53 static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf); 61 static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf);
54 static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf); 62 static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf);
158 r->headers_out.accept_ranges->value.data = (u_char *) "bytes"; 166 r->headers_out.accept_ranges->value.data = (u_char *) "bytes";
159 167
160 return ngx_http_next_header_filter(r); 168 return ngx_http_next_header_filter(r);
161 } 169 }
162 170
163 if (ngx_array_init(&r->headers_out.ranges, r->pool, 2, 171 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t));
164 sizeof(ngx_http_range_t)) 172 if (ctx == NULL) {
173 return NGX_ERROR;
174 }
175
176 if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t))
165 == NGX_ERROR) 177 == NGX_ERROR)
166 { 178 {
167 return NGX_ERROR; 179 return NGX_ERROR;
168 } 180 }
169 181
201 } 213 }
202 214
203 while (*p == ' ') { p++; } 215 while (*p == ' ') { p++; }
204 216
205 if (*p == ',' || *p == '\0') { 217 if (*p == ',' || *p == '\0') {
206 range = ngx_array_push(&r->headers_out.ranges); 218 range = ngx_array_push(&ctx->ranges);
207 if (range == NULL) { 219 if (range == NULL) {
208 return NGX_ERROR; 220 return NGX_ERROR;
209 } 221 }
210 222
211 range->start = start; 223 range->start = start;
247 if (start > end) { 259 if (start > end) {
248 rc = NGX_HTTP_RANGE_NOT_SATISFIABLE; 260 rc = NGX_HTTP_RANGE_NOT_SATISFIABLE;
249 break; 261 break;
250 } 262 }
251 263
252 range = ngx_array_push(&r->headers_out.ranges); 264 range = ngx_array_push(&ctx->ranges);
253 if (range == NULL) { 265 if (range == NULL) {
254 return NGX_ERROR; 266 return NGX_ERROR;
255 } 267 }
256 268
257 range->start = start; 269 range->start = start;
275 if (rc) { 287 if (rc) {
276 288
277 /* rc == NGX_HTTP_RANGE_NOT_SATISFIABLE */ 289 /* rc == NGX_HTTP_RANGE_NOT_SATISFIABLE */
278 290
279 r->headers_out.status = rc; 291 r->headers_out.status = rc;
280 r->headers_out.ranges.nelts = 0;
281 292
282 content_range = ngx_list_push(&r->headers_out.headers); 293 content_range = ngx_list_push(&r->headers_out.headers);
283 if (content_range == NULL) { 294 if (content_range == NULL) {
284 return NGX_ERROR; 295 return NGX_ERROR;
285 } 296 }
304 ngx_http_clear_content_length(r); 315 ngx_http_clear_content_length(r);
305 316
306 return rc; 317 return rc;
307 } 318 }
308 319
309
310 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t));
311 if (ctx == NULL) {
312 return NGX_ERROR;
313 }
314
315 ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module); 320 ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module);
316 321
317
318 r->headers_out.status = NGX_HTTP_PARTIAL_CONTENT; 322 r->headers_out.status = NGX_HTTP_PARTIAL_CONTENT;
319 323
320 if (r->headers_out.ranges.nelts == 1) { 324 if (ctx->ranges.nelts == 1) {
321 325
322 content_range = ngx_list_push(&r->headers_out.headers); 326 content_range = ngx_list_push(&r->headers_out.headers);
323 if (content_range == NULL) { 327 if (content_range == NULL) {
324 return NGX_ERROR; 328 return NGX_ERROR;
325 } 329 }
423 427
424 /* the size of the last boundary CRLF "--0123456789--" CRLF */ 428 /* the size of the last boundary CRLF "--0123456789--" CRLF */
425 429
426 len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN + sizeof("--" CRLF) - 1; 430 len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN + sizeof("--" CRLF) - 1;
427 431
428 range = r->headers_out.ranges.elts; 432 range = ctx->ranges.elts;
429 for (i = 0; i < r->headers_out.ranges.nelts; i++) { 433 for (i = 0; i < ctx->ranges.nelts; i++) {
430 434
431 /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */ 435 /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */
432 436
433 range[i].content_range.data = 437 range[i].content_range.data =
434 ngx_palloc(r->pool, 3 * NGX_OFF_T_LEN + 2 + 4); 438 ngx_palloc(r->pool, 3 * NGX_OFF_T_LEN + 2 + 4);
466 ngx_uint_t i; 470 ngx_uint_t i;
467 ngx_chain_t *out, *hcl, *rcl, *dcl, **ll; 471 ngx_chain_t *out, *hcl, *rcl, *dcl, **ll;
468 ngx_http_range_t *range; 472 ngx_http_range_t *range;
469 ngx_http_range_filter_ctx_t *ctx; 473 ngx_http_range_filter_ctx_t *ctx;
470 474
471 if (in == NULL || r->headers_out.ranges.nelts == 0) { 475 if (in == NULL) {
476 return ngx_http_next_body_filter(r, in);
477 }
478
479 ctx = ngx_http_get_module_ctx(r, ngx_http_range_body_filter_module);
480
481 if (ctx == NULL) {
472 return ngx_http_next_body_filter(r, in); 482 return ngx_http_next_body_filter(r, in);
473 } 483 }
474 484
475 buf = in->buf; 485 buf = in->buf;
476 486
477 if (ngx_buf_special(in->buf)) { 487 if (ngx_buf_special(in->buf)) {
478 return ngx_http_next_body_filter(r, in); 488 return ngx_http_next_body_filter(r, in);
479 } 489 }
480 490
481 ctx = ngx_http_get_module_ctx(r, ngx_http_range_body_filter_module);
482 if (ctx->offset) { 491 if (ctx->offset) {
483 goto overlapped; 492 goto overlapped;
484 } 493 }
485 494
486 range = r->headers_out.ranges.elts; 495 range = ctx->ranges.elts;
487 496
488 if (!buf->last_buf) { 497 if (!buf->last_buf) {
489 498
490 if (buf->in_file) { 499 if (buf->in_file) {
491 start = buf->file_pos + ctx->offset; 500 start = buf->file_pos + ctx->offset;
494 } else { 503 } else {
495 start = buf->pos - buf->start + ctx->offset; 504 start = buf->pos - buf->start + ctx->offset;
496 last = buf->last - buf->start + ctx->offset; 505 last = buf->last - buf->start + ctx->offset;
497 } 506 }
498 507
499 for (i = 0; i < r->headers_out.ranges.nelts; i++) { 508 for (i = 0; i < ctx->ranges.nelts; i++) {
500 if (start > range[i].start || last < range[i].end) { 509 if (start > range[i].start || last < range[i].end) {
501 goto overlapped; 510 goto overlapped;
502 } 511 }
503 } 512 }
504 } 513 }
508 * that are passed in the single buffer 517 * that are passed in the single buffer
509 */ 518 */
510 519
511 ctx->offset = ngx_buf_size(buf); 520 ctx->offset = ngx_buf_size(buf);
512 521
513 if (r->headers_out.ranges.nelts == 1) { 522 if (ctx->ranges.nelts == 1) {
514 523
515 if (buf->in_file) { 524 if (buf->in_file) {
516 buf->file_pos = range->start; 525 buf->file_pos = range->start;
517 buf->file_last = range->end; 526 buf->file_last = range->end;
518 } 527 }
525 return ngx_http_next_body_filter(r, in); 534 return ngx_http_next_body_filter(r, in);
526 } 535 }
527 536
528 ll = &out; 537 ll = &out;
529 538
530 for (i = 0; i < r->headers_out.ranges.nelts; i++) { 539 for (i = 0; i < ctx->ranges.nelts; i++) {
531 540
532 /* 541 /*
533 * The boundary header of the range: 542 * The boundary header of the range:
534 * CRLF 543 * CRLF
535 * "--0123456789" CRLF 544 * "--0123456789" CRLF