Mercurial > hg > nginx
comparison src/http/ngx_http_spdy_filter_module.c @ 5513:311803b21504
SPDY: body filter was replaced by c->send_chain() function.
It allows to use ngx_http_write_filter() and all its rate limiting logic.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Tue, 14 Jan 2014 16:24:45 +0400 |
parents | 9fffc0c46e5c |
children | b7ee1bae0ffa |
comparison
equal
deleted
inserted
replaced
5512:9fffc0c46e5c | 5513:311803b21504 |
---|---|
12 #include <ngx_http_spdy_module.h> | 12 #include <ngx_http_spdy_module.h> |
13 | 13 |
14 #include <zlib.h> | 14 #include <zlib.h> |
15 | 15 |
16 | 16 |
17 #define NGX_SPDY_WRITE_BUFFERED NGX_HTTP_WRITE_BUFFERED | |
18 | |
19 #define ngx_http_spdy_nv_nsize(h) (NGX_SPDY_NV_NLEN_SIZE + sizeof(h) - 1) | 17 #define ngx_http_spdy_nv_nsize(h) (NGX_SPDY_NV_NLEN_SIZE + sizeof(h) - 1) |
20 #define ngx_http_spdy_nv_vsize(h) (NGX_SPDY_NV_VLEN_SIZE + sizeof(h) - 1) | 18 #define ngx_http_spdy_nv_vsize(h) (NGX_SPDY_NV_VLEN_SIZE + sizeof(h) - 1) |
21 | 19 |
22 #define ngx_http_spdy_nv_write_num ngx_spdy_frame_write_uint16 | 20 #define ngx_http_spdy_nv_write_num ngx_spdy_frame_write_uint16 |
23 #define ngx_http_spdy_nv_write_nlen ngx_spdy_frame_write_uint16 | 21 #define ngx_http_spdy_nv_write_nlen ngx_spdy_frame_write_uint16 |
26 #define ngx_http_spdy_nv_write_name(p, h) \ | 24 #define ngx_http_spdy_nv_write_name(p, h) \ |
27 ngx_cpymem(ngx_http_spdy_nv_write_nlen(p, sizeof(h) - 1), h, sizeof(h) - 1) | 25 ngx_cpymem(ngx_http_spdy_nv_write_nlen(p, sizeof(h) - 1), h, sizeof(h) - 1) |
28 | 26 |
29 #define ngx_http_spdy_nv_write_val(p, h) \ | 27 #define ngx_http_spdy_nv_write_val(p, h) \ |
30 ngx_cpymem(ngx_http_spdy_nv_write_vlen(p, sizeof(h) - 1), h, sizeof(h) - 1) | 28 ngx_cpymem(ngx_http_spdy_nv_write_vlen(p, sizeof(h) - 1), h, sizeof(h) - 1) |
29 | |
30 | |
31 static ngx_chain_t *ngx_http_spdy_send_chain(ngx_connection_t *fc, | |
32 ngx_chain_t *in, off_t limit); | |
31 | 33 |
32 static ngx_inline ngx_int_t ngx_http_spdy_filter_send( | 34 static ngx_inline ngx_int_t ngx_http_spdy_filter_send( |
33 ngx_connection_t *fc, ngx_http_spdy_stream_t *stream); | 35 ngx_connection_t *fc, ngx_http_spdy_stream_t *stream); |
34 | 36 |
35 static ngx_http_spdy_out_frame_t *ngx_http_spdy_filter_get_data_frame( | 37 static ngx_http_spdy_out_frame_t *ngx_http_spdy_filter_get_data_frame( |
80 NGX_MODULE_V1_PADDING | 82 NGX_MODULE_V1_PADDING |
81 }; | 83 }; |
82 | 84 |
83 | 85 |
84 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | 86 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; |
85 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
86 | 87 |
87 | 88 |
88 static ngx_int_t | 89 static ngx_int_t |
89 ngx_http_spdy_header_filter(ngx_http_request_t *r) | 90 ngx_http_spdy_header_filter(ngx_http_request_t *r) |
90 { | 91 { |
605 cln->handler = ngx_http_spdy_filter_cleanup; | 606 cln->handler = ngx_http_spdy_filter_cleanup; |
606 cln->data = stream; | 607 cln->data = stream; |
607 | 608 |
608 stream->queued = 1; | 609 stream->queued = 1; |
609 | 610 |
611 c->send_chain = ngx_http_spdy_send_chain; | |
612 c->need_last_buf = 1; | |
613 | |
610 return ngx_http_spdy_filter_send(c, stream); | 614 return ngx_http_spdy_filter_send(c, stream); |
611 } | 615 } |
612 | 616 |
613 | 617 |
614 static ngx_int_t | 618 static ngx_chain_t * |
615 ngx_http_spdy_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | 619 ngx_http_spdy_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit) |
616 { | 620 { |
617 off_t size; | 621 off_t size; |
618 ngx_buf_t *b; | 622 ngx_buf_t *b; |
619 ngx_chain_t *cl, *out, **ln; | 623 ngx_chain_t *cl, *out, **ln; |
620 ngx_connection_t *fc; | 624 ngx_http_request_t *r; |
621 ngx_http_spdy_stream_t *stream; | 625 ngx_http_spdy_stream_t *stream; |
622 ngx_http_spdy_out_frame_t *frame; | 626 ngx_http_spdy_out_frame_t *frame; |
623 | 627 |
628 r = fc->data; | |
624 stream = r->spdy_stream; | 629 stream = r->spdy_stream; |
625 | 630 |
626 if (stream == NULL) { | 631 if (in == NULL) { |
627 return ngx_http_next_body_filter(r, in); | |
628 } | |
629 | |
630 fc = r->connection; | |
631 | |
632 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, fc->log, 0, | |
633 "spdy body filter \"%V?%V\"", &r->uri, &r->args); | |
634 | |
635 if (in == NULL || r->header_only) { | |
636 | 632 |
637 if (stream->queued) { | 633 if (stream->queued) { |
638 fc->write->delayed = 1; | 634 fc->write->delayed = 1; |
639 return NGX_AGAIN; | 635 } else { |
640 } | 636 fc->buffered &= ~NGX_SPDY_BUFFERED; |
641 | 637 } |
642 fc->buffered &= ~NGX_SPDY_WRITE_BUFFERED; | 638 |
643 | 639 return NULL; |
644 return NGX_OK; | |
645 } | 640 } |
646 | 641 |
647 size = 0; | 642 size = 0; |
648 ln = &out; | 643 ln = &out; |
649 | 644 |
650 do { | 645 do { |
651 b = in->buf; | 646 b = in->buf; |
652 #if 1 | 647 |
653 if (ngx_buf_size(b) == 0 && !ngx_buf_special(b)) { | |
654 ngx_log_error(NGX_LOG_ALERT, fc->log, 0, | |
655 "zero size buf in spdy body filter " | |
656 "t:%d r:%d f:%d %p %p-%p %p %O-%O", | |
657 b->temporary, | |
658 b->recycled, | |
659 b->in_file, | |
660 b->start, | |
661 b->pos, | |
662 b->last, | |
663 b->file, | |
664 b->file_pos, | |
665 b->file_last); | |
666 | |
667 ngx_debug_point(); | |
668 return NGX_ERROR; | |
669 } | |
670 #endif | |
671 cl = ngx_alloc_chain_link(r->pool); | 648 cl = ngx_alloc_chain_link(r->pool); |
672 if (cl == NULL) { | 649 if (cl == NULL) { |
673 return NGX_ERROR; | 650 return NGX_CHAIN_ERROR; |
674 } | 651 } |
675 | 652 |
676 size += ngx_buf_size(b); | 653 size += ngx_buf_size(b); |
677 cl->buf = b; | 654 cl->buf = b; |
678 | 655 |
684 } while (in); | 661 } while (in); |
685 | 662 |
686 if (size > NGX_SPDY_MAX_FRAME_SIZE) { | 663 if (size > NGX_SPDY_MAX_FRAME_SIZE) { |
687 ngx_log_error(NGX_LOG_ALERT, fc->log, 0, | 664 ngx_log_error(NGX_LOG_ALERT, fc->log, 0, |
688 "FIXME: chain too big in spdy filter: %O", size); | 665 "FIXME: chain too big in spdy filter: %O", size); |
689 return NGX_ERROR; | 666 return NGX_CHAIN_ERROR; |
690 } | 667 } |
691 | 668 |
692 frame = ngx_http_spdy_filter_get_data_frame(stream, (size_t) size, | 669 frame = ngx_http_spdy_filter_get_data_frame(stream, (size_t) size, |
693 out, cl); | 670 out, cl); |
694 if (frame == NULL) { | 671 if (frame == NULL) { |
695 return NGX_ERROR; | 672 return NGX_CHAIN_ERROR; |
696 } | 673 } |
697 | 674 |
698 ngx_http_spdy_queue_frame(stream->connection, frame); | 675 ngx_http_spdy_queue_frame(stream->connection, frame); |
699 | 676 |
700 stream->queued++; | 677 stream->queued++; |
701 | 678 |
702 return ngx_http_spdy_filter_send(fc, stream); | 679 if (ngx_http_spdy_filter_send(fc, stream) == NGX_ERROR) { |
680 return NGX_CHAIN_ERROR; | |
681 } | |
682 | |
683 return NULL; | |
703 } | 684 } |
704 | 685 |
705 | 686 |
706 static ngx_http_spdy_out_frame_t * | 687 static ngx_http_spdy_out_frame_t * |
707 ngx_http_spdy_filter_get_data_frame(ngx_http_spdy_stream_t *stream, | 688 ngx_http_spdy_filter_get_data_frame(ngx_http_spdy_stream_t *stream, |
799 } | 780 } |
800 | 781 |
801 stream->blocked = 0; | 782 stream->blocked = 0; |
802 | 783 |
803 if (stream->queued) { | 784 if (stream->queued) { |
804 fc->buffered |= NGX_SPDY_WRITE_BUFFERED; | 785 fc->buffered |= NGX_SPDY_BUFFERED; |
805 fc->write->delayed = 1; | 786 fc->write->delayed = 1; |
806 return NGX_AGAIN; | 787 return NGX_AGAIN; |
807 } | 788 } |
808 | 789 |
809 fc->buffered &= ~NGX_SPDY_WRITE_BUFFERED; | 790 fc->buffered &= ~NGX_SPDY_BUFFERED; |
810 | 791 |
811 return NGX_OK; | 792 return NGX_OK; |
812 } | 793 } |
813 | 794 |
814 | 795 |
937 | 918 |
938 static ngx_inline void | 919 static ngx_inline void |
939 ngx_http_spdy_handle_stream(ngx_http_spdy_connection_t *sc, | 920 ngx_http_spdy_handle_stream(ngx_http_spdy_connection_t *sc, |
940 ngx_http_spdy_stream_t *stream) | 921 ngx_http_spdy_stream_t *stream) |
941 { | 922 { |
942 ngx_connection_t *fc; | 923 ngx_event_t *wev; |
943 | |
944 fc = stream->request->connection; | |
945 | |
946 fc->write->delayed = 0; | |
947 | 924 |
948 if (stream->handled || stream->blocked) { | 925 if (stream->handled || stream->blocked) { |
949 return; | 926 return; |
950 } | 927 } |
951 | 928 |
952 stream->handled = 1; | 929 wev = stream->request->connection->write; |
953 | 930 |
954 stream->next = sc->last_stream; | 931 if (!wev->timer_set) { |
955 sc->last_stream = stream; | 932 wev->delayed = 0; |
933 | |
934 stream->handled = 1; | |
935 | |
936 stream->next = sc->last_stream; | |
937 sc->last_stream = stream; | |
938 } | |
956 } | 939 } |
957 | 940 |
958 | 941 |
959 static void | 942 static void |
960 ngx_http_spdy_filter_cleanup(void *data) | 943 ngx_http_spdy_filter_cleanup(void *data) |
992 ngx_http_spdy_filter_init(ngx_conf_t *cf) | 975 ngx_http_spdy_filter_init(ngx_conf_t *cf) |
993 { | 976 { |
994 ngx_http_next_header_filter = ngx_http_top_header_filter; | 977 ngx_http_next_header_filter = ngx_http_top_header_filter; |
995 ngx_http_top_header_filter = ngx_http_spdy_header_filter; | 978 ngx_http_top_header_filter = ngx_http_spdy_header_filter; |
996 | 979 |
997 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
998 ngx_http_top_body_filter = ngx_http_spdy_body_filter; | |
999 | |
1000 return NGX_OK; | 980 return NGX_OK; |
1001 } | 981 } |