comparison src/http/modules/ngx_http_range_filter_module.c @ 2121:b39c0040b3e4

support several buf's for single-part range patch by Maxim Dounin
author Igor Sysoev <igor@sysoev.ru>
date Tue, 29 Jul 2008 13:58:13 +0000
parents 0799703985ef
children 7155dbb2317e
comparison
equal deleted inserted replaced
2120:2f2052fdd882 2121:b39c0040b3e4
62 ngx_http_range_filter_ctx_t *ctx); 62 ngx_http_range_filter_ctx_t *ctx);
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_test_overlapped(ngx_http_request_t *r, 68 static ngx_int_t ngx_http_range_test_overlapped(ngx_http_request_t *r,
68 ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in); 69 ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
69 static ngx_int_t ngx_http_range_singlepart_body(ngx_http_request_t *r, 70 static ngx_int_t ngx_http_range_singlepart_body(ngx_http_request_t *r,
70 ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in); 71 ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
71 static ngx_int_t ngx_http_range_multipart_body(ngx_http_request_t *r, 72 static ngx_int_t ngx_http_range_multipart_body(ngx_http_request_t *r,
72 ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in); 73 ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
73 static ngx_int_t ngx_http_range_not_satisfiable(ngx_http_request_t *r);
74 74
75 static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf); 75 static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf);
76 static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf); 76 static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf);
77 77
78 78
549 549
550 if (ctx == NULL) { 550 if (ctx == NULL) {
551 return ngx_http_next_body_filter(r, in); 551 return ngx_http_next_body_filter(r, in);
552 } 552 }
553 553
554 if (ctx->ranges.nelts == 1) {
555 return ngx_http_range_singlepart_body(r, ctx, in);
556 }
557
558 /*
559 * multipart ranges are supported only if whole body is in a single buffer
560 */
561
554 if (ngx_buf_special(in->buf)) { 562 if (ngx_buf_special(in->buf)) {
555 return ngx_http_next_body_filter(r, in); 563 return ngx_http_next_body_filter(r, in);
556 } 564 }
557 565
558 if (ngx_http_range_test_overlapped(r, ctx, in) != NGX_OK) { 566 if (ngx_http_range_test_overlapped(r, ctx, in) != NGX_OK) {
559 return NGX_ERROR; 567 return NGX_ERROR;
560 }
561
562 if (ctx->ranges.nelts == 1) {
563
564 /*
565 * the optimized version for the responses
566 * that are passed in the single buffer
567 */
568
569 return ngx_http_range_singlepart_body(r, ctx, in);
570 } 568 }
571 569
572 return ngx_http_range_multipart_body(r, ctx, in); 570 return ngx_http_range_multipart_body(r, ctx, in);
573 } 571 }
574 572
622 620
623 static ngx_int_t 621 static ngx_int_t
624 ngx_http_range_singlepart_body(ngx_http_request_t *r, 622 ngx_http_range_singlepart_body(ngx_http_request_t *r,
625 ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in) 623 ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in)
626 { 624 {
625 off_t start, last;
627 ngx_buf_t *buf; 626 ngx_buf_t *buf;
627 ngx_chain_t *out, *cl, **ll;
628 ngx_http_range_t *range; 628 ngx_http_range_t *range;
629 629
630 buf = in->buf; 630 out = NULL;
631 ll = &out;
631 range = ctx->ranges.elts; 632 range = ctx->ranges.elts;
632 633
633 if (buf->in_file) { 634 for (cl = in; cl; cl = cl->next) {
634 buf->file_pos = range->start; 635
635 buf->file_last = range->end; 636 buf = cl->buf;
636 } 637
637 638 start = ctx->offset;
638 if (ngx_buf_in_memory(buf)) { 639 last = ctx->offset + ngx_buf_size(buf);
639 buf->pos = buf->start + (size_t) range->start; 640
640 buf->last = buf->start + (size_t) range->end; 641 ctx->offset = last;
641 } 642
642 643 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
643 return ngx_http_next_body_filter(r, in); 644 "http range body buf: %O-%O", start, last);
645
646 if (ngx_buf_special(buf)) {
647 *ll = cl;
648 ll = &cl->next;
649 continue;
650 }
651
652 if (range->end <= start || range->start >= last) {
653
654 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
655 "http range body skip");
656
657 buf->pos = buf->last;
658 continue;
659 }
660
661 if (range->start > start) {
662
663 if (buf->in_file) {
664 buf->file_pos += range->start - start;
665 }
666
667 if (ngx_buf_in_memory(buf)) {
668 buf->pos += (size_t) (range->start - start);
669 }
670 }
671
672 if (range->end <= last) {
673
674 if (buf->in_file) {
675 buf->file_last -= last - range->end;
676 }
677
678 if (ngx_buf_in_memory(buf)) {
679 buf->last -= (size_t) (last - range->end);
680 }
681
682 buf->last_buf = 1;
683 *ll = cl;
684 cl->next = NULL;
685
686 break;
687 }
688
689 *ll = cl;
690 ll = &cl->next;
691 }
692
693 if (out == NULL) {
694 return NGX_OK;
695 }
696
697 return ngx_http_next_body_filter(r, out);
644 } 698 }
645 699
646 700
647 static ngx_int_t 701 static ngx_int_t
648 ngx_http_range_multipart_body(ngx_http_request_t *r, 702 ngx_http_range_multipart_body(ngx_http_request_t *r,