comparison src/http/ngx_http_spdy_filter_module.c @ 5644:b948f9c73111

SPDY: avoid creating flush frames. Previously, an empty frame object was created for an output chain that contains only sync or flush empty buffers. But since 39d7eef2e332 every DATA frame has the flush flag set on its last buffer, so there's no need any more in additional flush buffers in the output queue and they can be skipped. Note that such flush frames caused an incorrect $body_bytes_sent value.
author Valentin Bartenev <vbart@nginx.com>
date Mon, 07 Apr 2014 23:35:33 +0400
parents 2bc609a4b516
children 701d6e17e42c
comparison
equal deleted inserted replaced
5643:436f3605195a 5644:b948f9c73111
623 ngx_http_spdy_connection_t *sc; 623 ngx_http_spdy_connection_t *sc;
624 624
625 r = fc->data; 625 r = fc->data;
626 stream = r->spdy_stream; 626 stream = r->spdy_stream;
627 627
628 #if (NGX_SUPPRESS_WARN)
629 size = 0;
630 #endif
631
632 while (in) {
633 size = ngx_buf_size(in->buf);
634
635 if (size || in->buf->last_buf) {
636 break;
637 }
638
639 in = in->next;
640 }
641
628 if (in == NULL) { 642 if (in == NULL) {
629 643
630 if (stream->queued) { 644 if (stream->queued) {
631 fc->write->delayed = 1; 645 fc->write->delayed = 1;
632 } else { 646 } else {
635 649
636 return NULL; 650 return NULL;
637 } 651 }
638 652
639 sc = stream->connection; 653 sc = stream->connection;
640
641 size = ngx_buf_size(in->buf);
642 654
643 if (size && ngx_http_spdy_flow_control(sc, stream) == NGX_DECLINED) { 655 if (size && ngx_http_spdy_flow_control(sc, stream) == NGX_DECLINED) {
644 fc->write->delayed = 1; 656 fc->write->delayed = 1;
645 return in; 657 return in;
646 } 658 }
848 860
849 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, stream->request->connection->log, 0, 861 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, stream->request->connection->log, 0,
850 "spdy:%ui create DATA frame %p: len:%uz flags:%ui", 862 "spdy:%ui create DATA frame %p: len:%uz flags:%ui",
851 stream->id, frame, len, flags); 863 stream->id, frame, len, flags);
852 864
853 if (len || flags) { 865 cl = ngx_chain_get_free_buf(stream->request->pool,
854 866 &stream->free_data_headers);
855 cl = ngx_chain_get_free_buf(stream->request->pool, 867 if (cl == NULL) {
856 &stream->free_data_headers); 868 return NULL;
857 if (cl == NULL) { 869 }
870
871 buf = cl->buf;
872
873 if (buf->start) {
874 p = buf->start;
875 buf->pos = p;
876
877 p += NGX_SPDY_SID_SIZE;
878
879 (void) ngx_spdy_frame_write_flags_and_len(p, flags, len);
880
881 } else {
882 p = ngx_palloc(stream->request->pool, NGX_SPDY_FRAME_HEADER_SIZE);
883 if (p == NULL) {
858 return NULL; 884 return NULL;
859 } 885 }
860 886
861 buf = cl->buf; 887 buf->pos = p;
862 888 buf->start = p;
863 if (buf->start) { 889
864 p = buf->start; 890 p = ngx_spdy_frame_write_sid(p, stream->id);
865 buf->pos = p; 891 p = ngx_spdy_frame_write_flags_and_len(p, flags, len);
866 892
867 p += NGX_SPDY_SID_SIZE; 893 buf->last = p;
868 894 buf->end = p;
869 (void) ngx_spdy_frame_write_flags_and_len(p, flags, len); 895
870 896 buf->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_get_data_frame;
871 } else { 897 buf->memory = 1;
872 p = ngx_palloc(stream->request->pool, NGX_SPDY_FRAME_HEADER_SIZE); 898 }
873 if (p == NULL) { 899
874 return NULL; 900 cl->next = first;
875 } 901 first = cl;
876 902
877 buf->pos = p; 903 last->buf->flush = 1;
878 buf->start = p;
879
880 p = ngx_spdy_frame_write_sid(p, stream->id);
881 p = ngx_spdy_frame_write_flags_and_len(p, flags, len);
882
883 buf->last = p;
884 buf->end = p;
885
886 buf->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_get_data_frame;
887 buf->memory = 1;
888 }
889
890 cl->next = first;
891 first = cl;
892
893 last->buf->flush = 1;
894 }
895 904
896 frame->first = first; 905 frame->first = first;
897 frame->last = last; 906 frame->last = last;
898 frame->handler = ngx_http_spdy_data_frame_handler; 907 frame->handler = ngx_http_spdy_data_frame_handler;
899 frame->stream = stream; 908 frame->stream = stream;