SPDY: fix tcp_nodelay and tcp_nopush handling

Yury Kirpichev ykirpichev at gmail.com
Thu Jun 20 11:08:38 UTC 2013


Hi,

Could you please take a look at the following patch.
In this patch I tried to fix handling for tcp_nodelay and tcp_nopush.
This patch is only applicable for SPDY over TCP connection (but not for
SPDY over SSL).

# HG changeset patch
# User ykirpichev at gmail.com
# Date 1371726192 -14400
# Branch fix_spdy_nopush_nodelay
# Node ID 71c426451cbe308c8a96cce175d34aeca39a266a
# Parent  982678c5c270f93a0c21ab6eb23cb123c0dc3df0
Fix spdy tcp_nodelay and tcp_nopush optioins handling

diff -r 982678c5c270 -r 71c426451cbe src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c Wed Jun 12 00:41:24 2013 +0900
+++ b/src/http/ngx_http_request.c Thu Jun 20 15:03:12 2013 +0400
@@ -314,6 +314,13 @@

 #if (NGX_HTTP_SPDY)
     if (hc->addr_conf->spdy) {
+        ngx_http_core_loc_conf_t   *clcf;
+
+        clcf = ngx_http_get_module_loc_conf(hc->conf_ctx,
+                                            ngx_http_core_module);
+
+        c->tcp_nodelay = clcf->tcp_nodelay ? NGX_TCP_NODELAY_UNSET :
NGX_TCP_NODELAY_DISABLED;
+        c->tcp_nopush = clcf->tcp_nopush ? NGX_TCP_NOPUSH_UNSET :
NGX_TCP_NOPUSH_DISABLED;
         rev->handler = ngx_http_spdy_init;
     }
 #endif
diff -r 982678c5c270 -r 71c426451cbe src/http/ngx_http_spdy.c
--- a/src/http/ngx_http_spdy.c Wed Jun 12 00:41:24 2013 +0900
+++ b/src/http/ngx_http_spdy.c Thu Jun 20 15:03:12 2013 +0400
@@ -154,6 +154,8 @@

 static void *ngx_http_spdy_zalloc(void *opaque, u_int items, u_int size);
 static void ngx_http_spdy_zfree(void *opaque, void *address);
+static ngx_int_t
+ngx_http_spdy_restore_nopush(ngx_connection_t *c, ngx_http_connection_t
*hc);


 static const u_char ngx_http_spdy_dict[] =
@@ -378,6 +380,11 @@

     sc->blocked = 0;

+    if (ngx_http_spdy_restore_nopush(c, sc->http_connection) != NGX_OK) {
+        ngx_http_spdy_finalize_connection(sc,
NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
+    }
+
     if (sc->processing) {
         if (rev->timer_set) {
             ngx_del_timer(rev);
@@ -447,6 +454,11 @@
         return;
     }

+    if (ngx_http_spdy_restore_nopush(c, sc->http_connection) != NGX_OK) {
+        ngx_http_spdy_finalize_connection(sc,
NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
+    }
+
     ngx_http_spdy_handle_connection(sc);
 }

@@ -2880,3 +2892,51 @@
                    "spdy zfree: %p", address);
 #endif
 }
+
+static ngx_int_t
+ngx_http_spdy_restore_nopush(ngx_connection_t *c, ngx_http_connection_t
*hc)
+{
+    // It is better to use NGX_SPDY_WRITE_BUFFERED here, but
+    // it is defined in ngx_http_spdy_filter_module.c
+    // So, just use !c->buffered
+    if (!c->buffered && !c->error) {
+        //no buffered data, so, we should clean nopush if needed
+        if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
+            if (ngx_tcp_push(c->fd) == -1) {
+                ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n "
failed");
+                return NGX_ERROR;
+            }
+
+            c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
+        }
+
+        if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
+        {
+            int tcp_nodelay = 1;
+
+            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
+
+            if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+                           (const void *) &tcp_nodelay, sizeof(int))
+                == -1)
+            {
+#if (NGX_SOLARIS)
+                /* Solaris returns EINVAL if a socket has been shut down */
+                c->log_error = NGX_ERROR_IGNORE_EINVAL;
+#endif
+
+                ngx_connection_error(c, ngx_socket_errno,
+                                     "setsockopt(TCP_NODELAY) failed");
+
+                c->log_error = NGX_ERROR_INFO;
+                return NGX_ERROR;
+            }
+
+            c->tcp_nodelay = NGX_TCP_NODELAY_SET;
+        }
+    }
+
+    return NGX_OK;
+}
+
+

BR/ Yury
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20130620/1ac4a6a9/attachment.html>


More information about the nginx-devel mailing list