diff 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
line wrap: on
line diff
--- a/src/http/ngx_http_spdy_filter_module.c
+++ b/src/http/ngx_http_spdy_filter_module.c
@@ -625,6 +625,20 @@ ngx_http_spdy_send_chain(ngx_connection_
     r = fc->data;
     stream = r->spdy_stream;
 
+#if (NGX_SUPPRESS_WARN)
+    size = 0;
+#endif
+
+    while (in) {
+        size = ngx_buf_size(in->buf);
+
+        if (size || in->buf->last_buf) {
+            break;
+        }
+
+        in = in->next;
+    }
+
     if (in == NULL) {
 
         if (stream->queued) {
@@ -638,8 +652,6 @@ ngx_http_spdy_send_chain(ngx_connection_
 
     sc = stream->connection;
 
-    size = ngx_buf_size(in->buf);
-
     if (size && ngx_http_spdy_flow_control(sc, stream) == NGX_DECLINED) {
         fc->write->delayed = 1;
         return in;
@@ -850,48 +862,45 @@ ngx_http_spdy_filter_get_data_frame(ngx_
                    "spdy:%ui create DATA frame %p: len:%uz flags:%ui",
                    stream->id, frame, len, flags);
 
-    if (len || flags) {
+    cl = ngx_chain_get_free_buf(stream->request->pool,
+                                &stream->free_data_headers);
+    if (cl == NULL) {
+        return NULL;
+    }
+
+    buf = cl->buf;
 
-        cl = ngx_chain_get_free_buf(stream->request->pool,
-                                    &stream->free_data_headers);
-        if (cl == NULL) {
+    if (buf->start) {
+        p = buf->start;
+        buf->pos = p;
+
+        p += NGX_SPDY_SID_SIZE;
+
+        (void) ngx_spdy_frame_write_flags_and_len(p, flags, len);
+
+    } else {
+        p = ngx_palloc(stream->request->pool, NGX_SPDY_FRAME_HEADER_SIZE);
+        if (p == NULL) {
             return NULL;
         }
 
-        buf = cl->buf;
-
-        if (buf->start) {
-            p = buf->start;
-            buf->pos = p;
-
-            p += NGX_SPDY_SID_SIZE;
+        buf->pos = p;
+        buf->start = p;
 
-            (void) ngx_spdy_frame_write_flags_and_len(p, flags, len);
+        p = ngx_spdy_frame_write_sid(p, stream->id);
+        p = ngx_spdy_frame_write_flags_and_len(p, flags, len);
 
-        } else {
-            p = ngx_palloc(stream->request->pool, NGX_SPDY_FRAME_HEADER_SIZE);
-            if (p == NULL) {
-                return NULL;
-            }
+        buf->last = p;
+        buf->end = p;
 
-            buf->pos = p;
-            buf->start = p;
-
-            p = ngx_spdy_frame_write_sid(p, stream->id);
-            p = ngx_spdy_frame_write_flags_and_len(p, flags, len);
-
-            buf->last = p;
-            buf->end = p;
+        buf->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_get_data_frame;
+        buf->memory = 1;
+    }
 
-            buf->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_get_data_frame;
-            buf->memory = 1;
-        }
+    cl->next = first;
+    first = cl;
 
-        cl->next = first;
-        first = cl;
-
-        last->buf->flush = 1;
-    }
+    last->buf->flush = 1;
 
     frame->first = first;
     frame->last = last;