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 }